<?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[Mokshesh Dafariya]]></title><description><![CDATA[Mokshesh Dafariya]]></description><link>https://blog.mokshesh.com</link><image><url>https://blog.mokshesh.com/img/substack.png</url><title>Mokshesh Dafariya</title><link>https://blog.mokshesh.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 29 Sep 2026 21:05:50 GMT</lastBuildDate><atom:link href="https://blog.mokshesh.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Mokshesh Dafariya]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[mokshesh@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[mokshesh@substack.com]]></itunes:email><itunes:name><![CDATA[Mokshesh Dafariya]]></itunes:name></itunes:owner><itunes:author><![CDATA[Mokshesh Dafariya]]></itunes:author><googleplay:owner><![CDATA[mokshesh@substack.com]]></googleplay:owner><googleplay:email><![CDATA[mokshesh@substack.com]]></googleplay:email><googleplay:author><![CDATA[Mokshesh Dafariya]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[The Copilot Retry Storm]]></title><description><![CDATA[3B: Bit By Byte &#183; Season 01 &#183; GitHub August 17 &#183; Chapter 06 &#183; 7-9K requests per second became 70-100K, amplified by the clients themselves.]]></description><link>https://blog.mokshesh.com/p/the-copilot-retry-storm</link><guid isPermaLink="false">https://blog.mokshesh.com/p/the-copilot-retry-storm</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Fri, 25 Sep 2026 18:14:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!w47-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.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_!w47-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!w47-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!w47-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!w47-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!w47-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!w47-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1636048,&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://blog.mokshesh.com/i/217434553?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.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_!w47-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!w47-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!w47-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!w47-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc7262ab-ef66-4f0c-b202-7adf3813ff2b_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>A service that normally sees 7,000 to 9,000 requests per second suddenly saw 70,000 to 100,000.</p><p>Sit with that number for a second. Ten times the traffic. And here is the part that makes it strange: none of that extra load came from a new feature launch, a marketing push, or a botnet. The amplification came from the client fleet. The very software that was supposed to be politely asking the Copilot Token Service for a token turned around and started shouting at it, all at once.</p><p>This is the chapter where the outage stops being a story about GitHub&#8217;s datacenter and becomes a story about everyone&#8217;s laptop.</p><h3><strong>GitHub says</strong></h3><p>Let me stay strict about sourcing, because that is the whole point of 3B.</p><p>GitHub says the Copilot Token Service normally sees roughly 7,000 to 9,000 requests per second. During the August 17 incident, it saw roughly 70,000 to 100,000 requests per second. That is about ten times normal.</p><p>GitHub attributes the spike to a latent retry bug in VS Code. According to GitHub, delayed responses from an internal endpoint resulted in roughly tenfold request amplification. In plain terms: an endpoint got slow, and because of the bug, slow responses made clients send far more requests than they normally would.</p><p>GitHub also says traffic was shifted regionally during the incident. And the recovery timeline is the tell. Most services were back around 16:36 UTC. Actions lagged until about 18:03 UTC. But the Copilot Token Service did not fully recover until about 21:02 UTC, with the incident marked resolved at 21:15 UTC. Copilot took hours longer than almost everything else.</p><p>That is the <em>what</em>. A latent client bug, a tenfold spike, and a service that trailed the rest of the recovery by more than four hours. Everything past this point is me reasoning, and I will say so.</p><h3><strong>The principle</strong></h3><p>Here is the principle, stated plainly:</p><p><strong>Your clients are part of your distributed system. You cannot control how the system behaves by controlling only the servers.</strong></p><p>We like to draw a box around &#8220;our system&#8221; and put it at the datacenter boundary. Inside the box: our services, our load balancers, our databases. Outside the box: users. But that line is a comfortable fiction. Every client running your code is a node in your system that you shipped, that makes decisions on your behalf, and that you do not operate. Its timeout is your timeout. Its retry loop is your retry loop. When millions of copies of it all make the same locally reasonable decision at the same moment, that decision becomes system behavior, and you did not get a vote at runtime. You got your vote when you shipped the client.</p><h3><strong>What this looks like in your world</strong></h3><p>You do not need Copilot&#8217;s scale to have this problem. You need a fleet of clients and one shared decision.</p><p>Think about a mobile app that refreshes on launch. A backend that calls a downstream service with a retry-on-error wrapper. A cron job deployed to a thousand machines that all wake at the top of the hour. In every case, the individual decision is sensible. &#8220;The request failed, so I will try again.&#8221; &#8220;The response is slow, so I will give up and reissue.&#8221; No single client is behaving badly. Each one is doing exactly what a careful engineer told it to do.</p><p>The trouble is that &#8220;each client independently decides to retry a slow request&#8221; is a coordination pattern in disguise. Slowness is a shared signal. When the server gets slow, it does not get slow for one client, it gets slow for all of them, at roughly the same time. So they all retry at roughly the same time. That synchronized wave has a name, and it is old: the thundering herd.</p><p>And here is the cruel twist specific to this incident. Retries are supposed to help you ride out a blip. But if the retry fires while the original request is still in flight (a timeout that is too aggressive, or a bug that reissues on a delayed response), you have not replaced one request with another. You have doubled it. Do that across a fleet, and a tenfold amplification is not shocking. It is arithmetic.</p><h3><strong>Why failover did not save Copilot</strong></h3><p>GitHub shifted traffic regionally during the incident. For a lot of the platform, that is exactly the right move. If Central US is saturated, send the work somewhere with headroom.</p><p>But think about what failover actually does. It moves the target. It picks up the destination and sets it down in a healthier region. That works beautifully when the load is a fixed quantity of legitimate demand and the only problem is where it lands.</p><p>It does not remove the client-generated load.</p><p>If ten times the normal request volume is being generated by client machines all over the world, moving the service to a fresh region can give that traffic more capacity, but it does not reduce the amplification. The same clients continue generating the same excess requests. The herd follows the target. You have not reduced the water, you have only changed which drain it goes down. One plausible interpretation, based on the shape of the incident, is that the other services benefited more directly from traffic rebalancing, easing a resource crunch, while Copilot continued facing amplified client demand that the rebalancing did not shrink.</p><p>There is a second, quieter reason, and it is the one I want you to remember longest. A server-side fix does not reach a deployed client. The bug was in VS Code, running on an enormous number of machines that GitHub does not control and cannot restart. Even once the root cause is understood, the fixed client has to be built, released, and then actually installed by users on their own schedule. Old client versions linger in an ecosystem for a very long time. So the pressure does not just stop when someone finds the bug. It can persist while the affected client population continues running the buggy behavior. <strong>We don&#8217;t know</strong> the exact mechanism GitHub used to bring the numbers down (whether it was throttling, an endpoint fix that unstuck the delayed responses, or the fleet churning to newer clients). The report does not say. But the shape of a long tail is consistent with load you cannot switch off from the server side.</p><h3><strong>Let&#8217;s experiment</strong></h3><p>I want to build the smallest thing that makes this visible, so you can see the amplification emerge rather than take my word for it.</p><p>Before the code, hold the herd in your head, because every number below is that picture with instruments attached. Each client is one machine on one desk, politely asking for a token on a steady heartbeat. Add them up and that is the calm baseline: one beat, one request. Now the endpoint slows down, all at once, for everyone. The slowness is the shared signal, so the herd reacts together, and the bug turns each patient request into a stack of impatient ones. The firehose is not aimed at the server. It <em>is</em> the clients.</p><p>So I built exactly that. It is small enough to run on a laptop, and it ships with this chapter (link at the end of the section). Two pieces:</p><pre><code><code>Fleet of clients (steady heartbeat)  -&gt;  one token endpoint (latency I fault)
</code></code></pre><p>The <strong>Fleet</strong> is 1,000 identical clients, each issuing one logical request every 500 milliseconds. That is a steady 2,000 requests per second, my stand-in for the calm 7-9K world. One honest caveat up front: the scale is illustrative, a thousand clients standing in for GitHub&#8217;s fleet. The amplification factor is the measured payload, and it does not depend on the absolute numbers.</p><p>The <strong>Endpoint</strong> answers in a fixed time. Healthy, it is fast (20 milliseconds). The fault makes it slow, 500 milliseconds, past the client&#8217;s timeout. I give it effectively unlimited capacity on purpose, so the only fault is latency and the only thing that can climb is the load the clients manufacture.</p><p>The <strong>Client</strong> carries the bug: its timeout is an aggressive 50 milliseconds, and on a timeout it reissues immediately, without canceling the request still in flight, without backoff, without jitter, without a budget.</p><p>Here is the actual output:</p><pre><code><code>Baseline (steady, healthy world): 2000 req/s

Scenario                        Endpoint   Amplify   Success
 Healthy baseline                2000       1.0x      100%
 Buggy client + slow endpoint    20002      10.0x     100%
 Same clients, failover          20002      10.0x     100%
 Fix: sane timeout               2000       1.0x      100%
 Fix: backoff + jitter           8046       4.0x      100%
 Fix: retry budget               2000       1.0x      100%
</code></code></pre><p>Read it top to bottom. Healthy, the fleet is a calm 2,000 requests per second, one attempt per beat. Fault the endpoint and turn on the bug, and the load reaching it jumps to about 20,000, a clean tenfold, because with a 500 millisecond response and a 50 millisecond timeout, the client can have roughly ten attempts associated with the same logical request before the original response arrives. The rough tenfold amplification follows from the relationship between the 500 millisecond response time and the 50 millisecond timeout.</p><p>Notice the success column: 100% the whole way down. Nothing is failing here. The clients are not fighting errors, they are simply generating ten times the necessary load off one slow response. That is the kind of amplification that can overwhelm a capacity-limited service, even when every individual client believes it is doing the right thing.</p><p>Now the row I care about most. <strong>Fail over to a fresh region</strong>, a fresh endpoint with effectively unlimited capacity in this experiment, and the amplification does not move. Still 10.0x. The clients generate the load, and the clients never changed, so moving the server just points the same firehose at a fresh drain. The herd follows the target.</p><p>The fix for the retry behavior has to reach the client, and the bottom three rows are it. A <strong>sane timeout</strong>, longer than a healthy response, and the amplification collapses to 1.0x, because a sane timeout prevents the client from abandoning requests that are still reasonably likely to complete, eliminating the duplicate in-flight attempts that create the amplification. <strong>Backoff and jitter</strong> alone bend it partway, to about 4x, spacing the retries out and breaking the lockstep. And a <strong>retry budget</strong>, a hard cap that says retries may add only a small fraction on top of real traffic and then must fail fast, keeps the amplification bounded in this experiment by preventing retries from continuing indefinitely. The retry budget limits duplicate attempts while the original request is still outstanding. In this experiment the endpoint eventually responds, so logical request success stays at 100%.</p><p>Everything here is measured from the real run: the attempts reaching the endpoint, the amplification factor, the success rate. The only thing that is illustrative is the fleet&#8217;s size, and the ratio does not care about that.</p><p>The code is <a href="https://github.com/moksheshd/experiments/tree/main/3b-bit-by-byte/season-01-github-august-17/06-client-retry-storm">in the season repo on GitHub</a>, under <code>06-client-retry-storm/</code>. Run <code>go run ./minimal</code> for the bare baseline-versus-storm table, <code>go run .</code> for the full run above, or <code>go run ./tui</code> to fault the endpoint yourself, press one key to fail over and watch the storm ignore it, then add client discipline and watch it collapse. The lesson the numbers make physical: moving the server does not change the amplification. The fix for a client storm has to reach the client.</p><h3><strong>Next in 3B: Bit By Byte</strong></h3><p>We have spent six chapters taking a system apart and watching it run out of things: concurrency, connection flow, retry budget, regional capacity, and now the client fleet itself. Next, in Chapter 7, The Fix Is Not the Lesson, we put it back together. What do you actually change so the next surge is survivable instead of fatal, and what is the one habit underneath all of it that outlasts any single outage?</p><p>Subscribe so the last chapter shows up with the rest.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[The Road Everyone Shares]]></title><description><![CDATA[3B: Bit By Byte &#183; Season 01 &#183; GitHub August 17 &#183; Chapter 05 &#183; The destinations can be healthy while the road between them fails.]]></description><link>https://blog.mokshesh.com/p/the-road-everyone-shares</link><guid isPermaLink="false">https://blog.mokshesh.com/p/the-road-everyone-shares</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Sun, 20 Sep 2026 09:25:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Nl_h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.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_!Nl_h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nl_h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Nl_h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Nl_h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Nl_h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nl_h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1729923,&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://blog.mokshesh.com/i/216552242?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.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_!Nl_h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Nl_h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Nl_h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Nl_h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb99fddbf-a43a-40c3-aaa2-0a7a90348898_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Picture the surface of GitHub as a wall of switches. Issues. Pull Requests. The REST and GraphQL APIs. Actions. Copilot. SAML and OIDC sign-in. SCIM. Team Sync. On a normal day these feel like separate products built by separate teams, and in most ways they are. They have their own code, their own databases, their own on-call rotations.</p><p>On the afternoon of August 17, a lot of those switches went dark at roughly the same moment.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>If you were only watching the symptoms, this looked like a coincidence too big to be a coincidence. How does the thing that opens an issue break at the same time as the thing that reviews a pull request break at the same time as the thing that hands Copilot a token? These features do not call each other. They do not share a database. Someone new to the incident might reasonably guess that ten things broke, which would mean ten separate bugs all deciding to show up on the same Monday.</p><p>That is almost never what happened. And the more interesting question is not &#8220;which service broke.&#8221; It is &#8220;which shared dependency did all of these features quietly route through, and why did that one thing get to take all of them down at once.&#8221;</p><p>That question is what this chapter is about.</p><h3><strong>GitHub says</strong></h3><p>Let me stay strict about sourcing, because that is the whole point of 3B.</p><p>GitHub&#8217;s <a href="https://www.githubstatus.com/incidents/zkxwbgr0cnmx">incident report</a> describes a chain, not a single snap. The immediate trigger was network saturation on load balancers in the Central US datacenter after a new traffic peak. An Istio sidecar hit its concurrency limit and did not scale the way it should have. Retry logic that was trying to help added more load instead of less.</p><p>Then comes the sentence I want to sit with for this chapter. GitHub says the original failure cascaded until four HAProxy nodes exhausted their flow limits, which degraded the gateway authentication path and caused widespread authentication latency and failures.</p><p>That is the hinge. The features that fell over included Issues, Pull Requests, the APIs, Actions, Copilot, SAML and OIDC authentication, SCIM, and Team Sync. That is a wide list. But notice what almost every item on it has in common. Before it can do its own job, it has to get one question answered somewhere along the request path: who are you, and are you allowed to do this?</p><p>When the authentication path at the gateway degrades, that question stops getting answered quickly, or stops getting answered at all. And a feature that cannot confirm who you are cannot safely let you do anything, even if its own logic is completely healthy. The pull request service did not forget how to show you a diff. It just never got past the front door.</p><p>That is what GitHub documents. Four HAProxy nodes run out of flow capacity, the gateway auth path degrades, and authentication latency and failures spread across the surfaces that depend on it. On a platform like this, that is most of them. (Exactly which surfaces routed through that path, and whether they all shared one route or several that happened to sit behind the same saturated layer, is a detail the writeup does not settle, and one I come back to at the end.)</p><h3><strong>The principle</strong></h3><p>Here is the principle, stated plainly:</p><p><strong>Independent features can still share a single road. A gateway, an authentication path, a network layer. And that shared road, not the features themselves, governs their reliability.</strong></p><p>We usually draw architecture diagrams as boxes with clean lines between them, and we admire how decoupled it all looks. But there is almost always a layer underneath the boxes that every request passes through on its way in. Call it the shared critical path. It is the dependency that many otherwise unrelated features route through, and when it degrades, all of them degrade regardless of their own health.</p><p>Authentication is a perfect example, because it is invisible until it is not. Nobody lists &#8220;auth&#8221; as a feature. Users do not think about it. But it sits on the entry road for Issues and Pull Requests and the API and Copilot alike. Saturate that one road and you have not broken one feature. You have broken the intersection every feature drives through.</p><p>The word for how far a single failure spreads is blast radius. The August 17 story is, in large part, a story about blast radius. A resource ran out (HAProxy flow limits), it degraded one shared thing (the gateway auth path), and because that shared thing sat on the critical path of so many features, the blast radius grew until it looked like the whole platform.</p><h3><strong>Translating this to your world</strong></h3><p>You do not run GitHub. You probably do run something with a shared road in it, and you may not have named it yet.</p><p>Think about the request lifecycle for your own service. Before your business logic runs, what does every request touch? An API gateway. An auth service or a token check. A service mesh sidecar. A shared connection pool to the primary database. A rate limiter. A DNS resolver. Any one of those is a candidate shared critical path, which means any one of them is a candidate for a blast radius far larger than its own importance suggests.</p><p>The test I use is simple. For each shared component, ask: if this gets slow, how many of my supposedly independent features get slow with it? If the honest answer is &#8220;most of them,&#8221; you have found a road, not a box. Its reliability is not its own private concern. It is the ceiling on everyone else&#8217;s reliability.</p><p>The good news is that this is a known problem with known shapes of answers. Isolation patterns exist precisely to shrink blast radius. Bulkheads keep one workload from draining a pool that another workload needs. Cells and separate pools give different tenants or different features their own copy of the shared thing, so saturating one does not starve the rest. The point of all of them is the same: make the road narrower in scope so that when it floods, the flood is contained.</p><h3><strong>Let&#8217;s experiment</strong></h3><p>Before the code, hold the intersection in your head, because every number below is that picture with instruments attached. The three endpoints are three destinations across town, each with a perfectly clear street of its own. The one shared road is the auth path they all merge onto before they can get anywhere. And the flood is one destination&#8217;s traffic swelling until it fills that shared road, so cars headed for the other two, healthy streets and all, sit stuck at the same intersection.</p><p>So I built exactly that. It is small enough to run on a laptop, and it ships with this chapter (link at the end of the section). It is not a reconstruction of GitHub&#8217;s topology, which is not public. It is a deliberately small model of the one mechanism at issue: a shared bottleneck turning one workload&#8217;s overload into everyone&#8217;s outage. Three independent endpoints, one shared auth gate in front of them:</p><pre><code><code>/notes    (200/s)  \
/tasks    (200/s)  -&gt;  AUTH GATE (30 slots, ~1500 auth/s)  -&gt;  handler (5ms)
/profile  (3000/s) /
</code></code></pre><p>The <strong>endpoints</strong> are <code>/notes</code>, <code>/tasks</code>, and <code>/profile</code>: three separate handlers with zero shared logic, each doing a trivially fast 5ms slice of its own work. That work runs only after the auth slot is released, so the handlers never add to the crowding at the gate. Nothing about them is fragile, and nothing connects them.</p><p>The <strong>auth gate</strong> is the one thing they share. It is a semaphore with 30 slots, and every request has to pass it before reaching its handler. Each auth check holds a slot for 20ms, so the gate can clear only about 1,500 auth checks per second in total, across all three endpoints. A request that cannot get a slot within 50ms is turned away: a timeout at the gate, not a fault in any handler behind it. The request never reached one.</p><p>The <strong>load</strong> is open-loop and flat, one generator per endpoint that never backs off. <code>/notes</code> and <code>/tasks</code> are light and innocent, 200 requests per second each. <code>/profile</code> floods at 3,000 per second, which by itself is twice the entire gate&#8217;s capacity.</p><p>First run, all three share the one gate. Here is the actual output:</p><pre><code><code>Endpoint   Offered  Success  p50 lat  p95 lat
/notes     200      39%      71ms     83ms
/tasks     200      44%      72ms     94ms
/profile   3000     43%      72ms     86ms</code></code></pre><p>Read the success column first. <code>/profile</code> is flooding, so of course it fails most of what it offers. But look at <code>/notes</code> and <code>/tasks</code>. Each is offering a trivial 200 requests per second, each has a handler that is perfect and untouched, and each is succeeding only about 40% of the time, right alongside the flood. Their latency has tripled too, from a healthy 25ms to over 70ms. Nothing about those two endpoints changed. They simply share <code>/profile</code>&#8216;s road, and <code>/profile</code> filled it. The three success rates fall together, in lockstep, because they were never really three independent systems. They are three tenants of one road.</p><p>The specific number is not arbitrary. The gate clears about 1,500 of the 3,400 requests offered each second, roughly 44% overall. All three endpoints pour into the same queue for that one gate, so over any window each endpoint&#8217;s share of the requests that get through tracks its share of the requests coming in. That is why all three land near the same 44% success rate, instead of the flood crowding the light endpoints out entirely, and why a light, innocent endpoint pays nearly the same rate as the flood it happens to share a gate with. The exact split drifts run to run with scheduling and timing, but the shape holds.</p><p>Now give each its own lane. Same load, same flood, same handlers, but each endpoint gets its own gate instead of sharing one:</p><pre><code><code>Endpoint   Offered  Success  p50 lat  p95 lat
/notes     200      100%     25ms     28ms
/tasks     200      100%     25ms     28ms
/profile   3000     16%      71ms     77ms</code></code></pre><p>The picture splits in two. <code>/notes</code> and <code>/tasks</code> snap back to 100% success at 25ms, because their gates were never crowded to begin with. <code>/profile</code> still tanks, because it genuinely offers far more than one lane can clear: each endpoint&#8217;s own gate holds a third of the slots (10 of the 30), so it passes only about 500 auth checks a second, and <code>/profile</code> is still offering 3,000. But now that failure is its own. The flood is exactly as big as before. The only thing that changed is how far the damage reaches. That is a bulkhead: not more capacity, just a wall that keeps one workload&#8217;s flood from draining everyone else&#8217;s road.</p><p>One honest note on those tables: unlike the earlier chapters, there is no modeled number here. The offered rates, the success rates, and the latencies are all measured end to end from real goroutines passing through a real semaphore with real auth waits. Each table is a single run, measured over a three-second window after a one-second warmup, with latency recorded only for requests that succeeded. The whole result is the per-endpoint contrast between the two arrangements, and you can reproduce it.</p><p>The code is <a href="https://github.com/moksheshd/experiments/tree/main/3b-bit-by-byte/season-01-github-august-17/05-shared-bottleneck">in the season repo on GitHub</a>, under <code>05-shared-bottleneck/</code>. Run <code>go run ./minimal</code> for the bare shared bottleneck and one plain table, <code>go run .</code> for the full shared-vs-bulkhead run above, or <code>go run ./tui</code> to dial <code>/profile</code>&#8216;s flood yourself and toggle the arrangement live: watch all three success bars fall together on the shared gate, then press one key and watch <code>/notes</code> and <code>/tasks</code> jump back to full while only <code>/profile</code> stays down. The reasoning stands on its own too: a shared dependency sets the ceiling on everyone who routes through it, and the surest way to shrink a blast radius is to stop sharing the thing that carries it.</p><h3><strong>What we don&#8217;t know</strong></h3><p>I want to be honest about the edges of the evidence, because that honesty is the discipline.</p><p>GitHub tells us four HAProxy nodes exhausted their flow limits and that this degraded the gateway auth path. What the writeup does not hand us is the exact topology: how many features shared those specific nodes, whether every affected surface authenticated through the same path or through several that happened to sit behind the same saturated layer, or what the flow limit numbers actually were. My lab reproduces the mechanism, a shared bottleneck spreading a blast radius, but it is my model of the shape, not a recovered copy of GitHub&#8217;s internals. When I say &#8220;authentication was the shared road,&#8221; I am reasoning from the documented symptom list plus a plainly stated cause. I am not claiming to have seen their config.</p><p>That gap is fine. Naming it is what keeps the reasoning trustworthy.</p><h3><strong>Next in 3B: Bit By Byte</strong></h3><p>We have been treating the traffic as if it just arrived. It did not entirely. Some of it was manufactured by clients that were trying to be helpful. Next, in Chapter 6, The Copilot Retry Storm, we follow the thread of how a latent client retry bug amplified one service&#8217;s traffic from its normal 9,000 requests per second toward 100,000, and what a self-inflicted flood teaches you about the difference between load you receive and load you create.</p><p>If you want the whole teardown, one question at a time, subscribe and come with me.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[Every Team Has Its Kurukshetra ]]></title><description><![CDATA[Conflict is inevitable. Whether it heals you or breaks you is not.]]></description><link>https://blog.mokshesh.com/p/every-team-has-its-kurukshetra</link><guid isPermaLink="false">https://blog.mokshesh.com/p/every-team-has-its-kurukshetra</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Sat, 19 Sep 2026 08:08:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!NGso!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.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_!NGso!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NGso!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!NGso!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!NGso!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!NGso!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NGso!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1778158,&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://blog.mokshesh.com/i/216414681?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.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_!NGso!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!NGso!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!NGso!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!NGso!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f885744-453c-4db2-a4ee-c6b0156b85df_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The war of the Mahabharat is a family fight. This is the detail that is easy to forget. The way the story is commonly told, Kurukshetra is not two nations at war. It is one family turning its weapons on itself: cousins raised in the same palace, taught by the same teacher, blessed by the same grandfather. Bhishma, the grandfather who loves both sides, fights for the Kauravas because his vows and his loyalty to the throne bind him. Drona, the teacher, aims arrows at the students he trained. Karna and Arjuna, who (as the story goes) are brothers without both of them knowing it, hunt each other across the field.</p><p>And here is what is at stake, so the scene lands even if you have never opened the epic: this is not a war anyone truly wanted. It is a war that, despite repeated attempts to prevent it, eventually became impossible to contain. By the end, almost everyone on that field is dead, on both sides. A whole family destroys itself over a conflict that kept escalating.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Because the way I read it, the tragedy of the Mahabharat is not that a conflict happened. Conflicts happen. The tragedy is <em>how</em> it was fought. It was allowed to grow, over years, from the dice game into a total war, until the conflict had reached a point where the cost would be almost unimaginable. At many points along the way, the fight could have been cooled. Krishna even went as a final emissary of peace, but that effort failed. And so the field is remembered for the slaughter, not for the family it used to be.</p><h3><strong>The principle</strong></h3><p>On any team worth being on, conflict is not a sign of failure. It is usually a sign that people care about different things and are willing to say so. A team that never disagrees openly is not necessarily a healthy team. Sometimes it is a team where people no longer feel safe telling the truth. So the goal is not to get rid of conflict. It is to fight it in a way that leaves the team more whole afterward, not less.</p><p>There are, roughly, two kinds of conflict, and from a distance they can look the same. One kind is about the <em>work</em>: which approach, whose data, what tradeoff. That kind, argued in the open, tends to make decisions better. The other kind is about <em>ego and position</em>: who is right, who won, who feels threatened. That kind, left alone, slowly turns colleagues into opponents. And once a fight becomes personal, almost no outcome feels good enough, because the fight is no longer about the thing you were actually deciding.</p><p>The way I read Kurukshetra, the whole disaster is the story of the first kind of conflict (who should rule, an honest and real question) being allowed to curdle into the second (who must be <em>destroyed</em>). The escalation is the villain here, not the disagreement.</p><p>Think of a house fire. A small flame in a pan is a normal part of cooking. The problem is when no one deals with it, and it reaches the curtain, then the wall, then the whole kitchen. The flame was never the danger. Leaving it to spread was. Team conflict works the same way.</p><h3><strong>The translation</strong></h3><p>Early in my career, I was leading a small team building an IVR SDK, and two of my most senior engineers could not agree on the architecture. One wanted a single, traditional build. The other wanted to break it into smaller services. At first this was exactly the good kind of fight: two capable people, two real philosophies, argued in the open. I let it run, because it was making the design better.</p><p>Then it shifted. The comments in code reviews got sharper. The disagreement stopped being about the design and started being about who was the better engineer. The room went tense. Standups got quiet in the wrong way. That was the moment that mattered, and I almost missed it, because I was still watching the technical argument and not the two people having it.</p><p>What fixed it was not picking a winner. I met each of them alone to hear the real concern, then put the two designs into a structured debate with clear criteria, and brought in a respected architect from another team as a neutral outside voice. We landed on a hybrid neither had proposed alone. The feature shipped. But the lesson stayed with me: the disagreement was never the problem. The moment it became personal was.</p><p>Watch how a team handles conflict and you can often see whether it will heal or fracture.</p><ul><li><p><strong>Healing teams fight about the work, out loud, and then decide.</strong> The disagreement is on the table, everyone gets heard, a call gets made, and people commit to it, including the ones who lost the argument. The conflict is <em>closed.</em></p></li><li><p><strong>Fracturing teams take it underground.</strong> The disagreement goes quiet in the room and loud in the side channels: the DMs, the hallway, the after-meeting meeting. Nothing gets decided, so it just piles up. Like the years between the dice game and the war, resentment compounds until it is no longer about the original issue at all.</p></li><li><p><strong>The escalation tell.</strong> When people start needing to be <em>right</em> more than they need the team to <em>win</em>, you may be watching a Kurukshetra begin. That is often the moment to step in, before positions harden into vows no one can climb down from.</p></li></ul><p>Say you are a new manager and two engineers on your team disagree about how to build something. At first it sounds healthy: one wants the fast approach, the other wants the safe one, and they argue it in standup. Good. But a week later you notice the arguing has gone quiet, and instead they are each quietly building their own version, cc-ing you on messages that are really about the other person. That is the flame reaching the curtain. The disagreement did not go away. It went underground and turned personal. Your job is not to pick the winner. It is to pull the fight back above ground and back onto the work.</p><p>Because a leader&#8217;s job in team conflict is usually not to prevent it. It is to keep it about the work, keep it in the open, and <em>close it</em>, so it does not ferment into the kind of conflict that ends teams.</p><h3><strong>The practice</strong></h3><p>Next time conflict flares on your team, and at some point it will, try three things:</p><ol><li><p><strong>Name which kind it is, out loud.</strong> Something like: &#8220;I think we&#8217;re disagreeing about the approach here, not about each other. Let&#8217;s keep it there.&#8221; Naming it early helps keep a work conflict from sliding into an ego conflict.</p></li><li><p><strong>Bring the underground conversation up.</strong> If the real disagreement is happening in DMs and hallways, say so, gently: &#8220;It feels like there&#8217;s a concern we&#8217;re not talking about openly. Let&#8217;s put it on the table.&#8221; Silence is where resentment compounds.</p></li><li><p><strong>Close the loop.</strong> After the argument, make the decision explicit and ask for commitment, including from the people who did not get their way. An unclosed conflict rarely disappears. It waits.</p></li></ol><p>Every team has its Kurukshetra: a moment when what people care about collides. The field is only remembered for the slaughter because no one cooled the fight in time. You can.</p><p><em>Next week: The Battle Within, the opponent you can&#8217;t out-argue.</em></p><p><em>This is part 6 of a 10-part series on the inner game of organizational life, drawn from the Mahabharat. Subscribe to get one episode every Thursday, one battle at a time.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[Choosing Your Battles]]></title><description><![CDATA[Saying no is not time management. It&#8217;s self-respect.]]></description><link>https://blog.mokshesh.com/p/choosing-your-battles</link><guid isPermaLink="false">https://blog.mokshesh.com/p/choosing-your-battles</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Sun, 13 Sep 2026 12:32:22 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RYRg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.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_!RYRg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RYRg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!RYRg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!RYRg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!RYRg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RYRg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2093108,&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://blog.mokshesh.com/i/215491186?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.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_!RYRg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!RYRg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!RYRg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!RYRg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0f470e1-363f-4eef-85d4-88bd65d3ee3a_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>When the great war of the Mahabharat finally comes, one of the strongest men alive looks at it and walks away.</p><p>His name is Balarama. In the way the story is often told, he is Krishna&#8217;s elder brother, and one of the mightiest warriors of the age. He had trained fighters on both sides: Bhima among the Pandavas, and Duryodhana among the Kauravas. Both sides knew his strength, and both had reason to want him. This is a war that will kill most of the men on that field and end an entire generation. And Balarama decides it is not his to fight. He leaves on a long pilgrimage and returns only near the end, in time to witness the final confrontation between Bhima and Duryodhana.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>It is easy to read that as weakness, as running from the hard thing. The way I read it, it is the opposite. Balarama looked at a fight everyone assumed he would join, and made a deliberate choice: not this one. He seems to have understood something simple. A warrior who fights every battle offered to him is not strong. He is just available.</p><p>The Pandavas, who had suffered years of exile and humiliation, make a similar choice from the other direction. They do not begin by demanding the whole kingdom back. As it is commonly told, their final offer is five villages. Five. Not because they do not want the fight, but as a last attempt to secure a settlement they could live with, and avoid a war they know will cost far more than it can ever return. It is Duryodhana, the Kaurava prince, who refuses to give up even a needle&#8217;s point of land. He is the one who cannot choose his battles. In the story, that inability destroys him and nearly everyone he loves.</p><h3><strong>The principle</strong></h3><p>There are three habits that look separate but are really the same thing. All three are what I mean by choosing your battles.</p><ol><li><p><strong>Restraint.</strong> Not fighting a battle just because it landed in front of you.</p></li><li><p><strong>Prioritization.</strong> Spending your limited energy on the few things that truly matter.</p></li><li><p><strong>Saying no.</strong> Declining the requests, meetings, and fights that were never yours to take.</p></li></ol><p>We tend to treat these as small logistics. Calendar tips. Productivity tricks. They are not. They are one discipline, and at heart it is a discipline of self-respect. Every yes is a no to something else, even when you can&#8217;t see the something else yet. A person who almost never says no is not more generous than the rest of us. In practice, they have handed the ranking of their own time to whoever asked last and loudest.</p><p>Duryodhana&#8217;s tragedy, the way I read it, is that he could not tell a battle worth fighting from a battle that was merely available. His pride turned every slight into a war. And someone who fights every battle tends to lose the one that actually mattered, because they show up to it already exhausted.</p><h3><strong>The translation</strong></h3><p>A few years ago I made this exact mistake, and it cost real money.</p><p>We needed reporting for our product, and early on I built it the quick way: pointing our reporting tool straight at the production database. It worked, and I was proud of how little it took. When teammates suggested we invest in a proper, separate data pipeline, I pushed back every time. Too heavy. Not worth it. We were fine.</p><p>We were not fine. As we grew, those reporting queries started dragging down the actual application, the thing customers depended on. Infra costs climbed. We burned engineering weeks patching around a problem I would not name out loud.</p><p>The honest truth is that I had stopped making a technical call. I was defending my original decision because it was mine. I had turned &#8220;keep the simple setup&#8221; into a battle, and I kept fighting it long after the cost stopped making sense.</p><p>When we finally moved reporting onto its own pipeline, the application steadied and the noise went away. I lost the battle I should have conceded months earlier because I refused to fight the one that actually mattered.</p><p>The lesson was not to avoid difficult decisions. It was to stop spending energy defending a decision that no longer served the work.</p><p>For a new manager, the inability to choose battles shows up almost everywhere:</p><ul><li><p><strong>The meeting you attend because you were invited</strong>, not because you are needed. Being available is not the same as contributing.</p></li><li><p><strong>The disagreement you win</strong> that quietly costs you a relationship you will need next quarter. Some battles are more expensive to win than to lose.</p></li><li><p><strong>The pet project you can&#8217;t put down</strong> even after it has stopped mattering, because your ego is now attached to it.</p></li><li><p><strong>The yes you gave</strong> because saying no felt rude, and now you resent the person you said it to.</p></li></ul><p>Here is a way to picture it. Think of your attention as a small budget you get to spend once, each day. Every &#8220;sure, I&#8217;ll take that&#8221; is money leaving the account. Most new managers never see the balance drop, because saying yes feels free in the moment. The cost shows up later, on the work that actually had your name on it.</p><p>Say a peer asks you to join a working group sorting out a process problem in another team. It is interesting, you have opinions, and saying yes feels helpful. But it is not your team&#8217;s problem, and it will eat two hours a week for a quarter, time your own people needed. That is a battle that is available, not yours. Handing it back, kindly, is not laziness. It is you defending the budget for the work only you can do.</p><p>Choosing battles well comes down to one honest question, asked before you commit: is this mine to fight, and is it worth what it will cost? Many requests fail one test or the other. The steadiest managers I have watched are rarely the ones who do the most. They are the ones who have decided, clearly, what they will not do, and can say so without a long apology.</p><p>None of this is about becoming the person who says no to everything and calls it focus. Choosing your battles means you say yes on purpose too, and then actually show up for the ones you chose.</p><h3><strong>The practice</strong></h3><p>This week, run everything asked of you through one filter, and then act on it:</p><ol><li><p><strong>&#8220;Is this mine?&#8221;</strong> Is this really my battle, or am I fighting it only because it got handed to me and no one else picked it up? If it is not yours, hand it back, gently and early.</p></li><li><p><strong>&#8220;Is it worth the cost?&#8221;</strong> Not just the hours. The relationship you spend, the focus you lose, the thing you now can&#8217;t do. Some wins are not worth their price.</p></li><li><p><strong>Say one clean no.</strong> Decline one thing you would normally accept out of habit or guilt. You do not owe a long defense. &#8220;I can&#8217;t take this on and do it well&#8221; is a complete sentence. Notice that the sky does not fall.</p></li></ol><p>Balarama walked away from the biggest war of the age. The way I read it, his decision was not weakness. It was a choice about what he was, and was not, willing to take responsibility for. Duryodhana refused to concede even a needle&#8217;s point of land, and lost everything. The difference was not strength. It was the ability to choose.</p><p><em>Next week: Every Team Has Its Kurukshetra. Conflict is inevitable; what you do with it isn&#8217;t.</em></p><p><em>This is part 5 of a 10-part series on the inner game of organizational life, drawn from the Mahabharat. Subscribe to get one episode every Thursday, one battle at a time.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[Winning the Meeting Before It Starts]]></title><description><![CDATA[The room is decided before anyone walks into the room.]]></description><link>https://blog.mokshesh.com/p/winning-the-meeting-before-it-starts</link><guid isPermaLink="false">https://blog.mokshesh.com/p/winning-the-meeting-before-it-starts</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Sun, 06 Sep 2026 20:01:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PWbw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.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_!PWbw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PWbw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 424w, https://substackcdn.com/image/fetch/$s_!PWbw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 848w, https://substackcdn.com/image/fetch/$s_!PWbw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 1272w, https://substackcdn.com/image/fetch/$s_!PWbw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PWbw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png" width="1374" height="1145" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1145,&quot;width&quot;:1374,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1897559,&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://blog.mokshesh.com/i/214471968?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.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_!PWbw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 424w, https://substackcdn.com/image/fetch/$s_!PWbw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 848w, https://substackcdn.com/image/fetch/$s_!PWbw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.png 1272w, https://substackcdn.com/image/fetch/$s_!PWbw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35155323-bf2c-408d-8ffc-1013965e3551_1374x1145.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Before the great war in the Mahabharat, Krishna travels to the enemy court on one last mission: to stop the war.</p><p>The deal is simple. If the Kauravas give the Pandavas just five villages, everyone goes home and no one dies. Krishna walks into the most powerful court in the land and argues for peace with everything he has.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>And Krishna knows how unlikely peace is with Duryodhana.</p><p>He knows Duryodhana, the Kaurava prince. He knows how the man thinks. So why make the trip at all?</p><p>Not simply to change Duryodhana&#8217;s mind. Krishna goes so that when the war comes, no one can say the Pandavas started it. He wants every elder and king in that hall to watch peace get offered honestly, and refused. The meeting he appears to be losing is doing exactly what he needs. He walks out having &#8220;failed,&#8221; and that failure is the win.</p><p>Krishna didn&#8217;t go to win the argument in the room. He went because he had already decided what the room was <em>for.</em></p><p>Here is the move, and it is simpler than it sounds. He treated the meeting as a place to <strong>confirm</strong> an outcome, not to <strong>create</strong> one. He argued for peace with everything he had. But he wasn&#8217;t counting on that argument to move Duryodhana. He was making the case for the record, so the whole hall would watch it play out exactly as he needed.</p><h3><strong>The principle</strong></h3><p>Meetings rarely decide things. The deciding mostly happens before, in the quiet. The meeting is where it gets confirmed out loud.</p><p>Put another way: an important meeting should almost never be the first place a key person encounters the idea, the problem, or the decision. This is easy to forget. As a new manager, you walk into the big meeting hoping to win it live: on your feet, in front of everyone, in the one room where changing a mind is hardest. That feels like leadership. It is actually the hardest way to get a yes.</p><p>Think about why a meeting is a bad place to persuade anyone:</p><ul><li><p><strong>People are being watched.</strong> Changing your mind in front of everyone feels like losing face, so people dig in instead.</p></li><li><p><strong>People feel rushed.</strong> A real concern needs time to sit with. In the room, they either blurt a half-formed version of it or stay quiet and kill your idea later.</p></li><li><p><strong>People are surprised.</strong> When someone hears your idea for the first time in the room, their first instinct is to defend, not to consider. Surprise triggers defense.</p></li></ul><p>So the real work happens before the meeting, in the quiet. The pre-read someone actually opened. The 1:1 where the key person got to react without an audience. The hallway sentence that let them object where saving face costs nothing. By the time everyone sits down, the big surprises are gone. Whatever disagreement is left is disagreement you already knew about, and the meeting is where you resolve it in the open, not where you discover it for the first time.</p><p>Here is a picture that helps: a wedding. The couple decided to marry weeks ago. The ceremony doesn&#8217;t create the marriage. It makes it official and lets everyone witness it. No one walks into their own wedding hoping to win an argument about whether to get married. Treat your important meetings the same way. Do the real work first. Let the room make it official.</p><p>So the question is never &#8220;how do I perform in the room?&#8221; It is &#8220;what do I need the room to confirm, and have I secured that yet?&#8221;</p><h3><strong>The translation</strong></h3><p>Early in my career, I was handed my first big project: build an IVR system for an important client. I thought I knew exactly what we were building. I gathered the team, assigned people, and walked into the kickoff ready to go.</p><p>Twenty minutes in, it fell apart. What I thought was a simple system, my boss thought was something three times the size. We had understood the project completely differently, and now that gap was sitting on the table in front of everyone, with people already assigned to the wrong work.</p><p>The mistake wasn&#8217;t the misunderstanding. It was that I&#8217;d let the meeting be the first place we checked whether we agreed. I had assumed alignment instead of confirming it.</p><p>So I fixed it the slow way. Before the next project, I sat with each stakeholder privately and got explicit agreement on scope, one conversation at a time, long before anyone gathered in a room. After that, kickoffs stopped being where we discovered disagreements. They became where we confirmed we didn&#8217;t have any.</p><p>&#8220;Winning before the meeting&#8221; is not a trick, and it is not politics in a bad sense. It is three ordinary things, done ahead of time.</p><p><strong>No one is surprised.</strong> If a key person is hearing your proposal for the first time in the room, you are already behind. The people who matter should have seen it privately, with room to object where saving face costs nothing. You are not hiding the ball. You are giving them the chance to say no somewhere it is cheap to say.</p><p>Say you want to propose a new on-call rotation. Before the meeting, you send it to the two engineers most likely to hate it and ask, &#8220;What am I missing?&#8221; One of them points out it breaks during holidays. You fix it. Now, in the room, that objection never even comes up, because you already handled it in private.</p><p><strong>The hard questions are already answered.</strong> You should know the three toughest objections before you walk in, because you asked the people likely to raise them and either fixed the concern or decided where you&#8217;ll hold your ground. The important objections should not be new to you.</p><p><strong>You know what the room is for.</strong> Is it a decision? Just alignment? Cover from your boss so you can move? A place to talk through a disagreement you already know is there? Krishna&#8217;s meeting looked like a negotiation, but it was really about proof: proof that peace was offered. If you can&#8217;t say in one sentence what you need the room to confirm, you&#8217;ll drift, and the loudest person there will name it for you.</p><p>Put simply: you are not going in to create the outcome. You are going in to confirm one you already built. Which means most of your prep is not about the meeting at all. It is the conversations that happen before it. The deck is the smallest part.</p><h3><strong>The practice</strong></h3><p>Before your next important meeting, do the work that actually decides it:</p><ol><li><p><strong>List everyone whose &#8220;no&#8221; would sink this, and everyone the decision actually affects.</strong> These are often the same people: the ones living with the outcome are the ones whose quiet no shows up later. This is not about hunting for powerful people and getting them onside in secret. Talk to each one <em>before</em> the meeting, even a two-line message, and let them react in private, where they can change their mind without an audience.</p></li><li><p><strong>Write the three hardest questions</strong> you could be asked. If you don&#8217;t have a real answer to one of them, that is not a meeting problem, it is a homework problem. Fix it before, not during.</p></li><li><p><strong>Finish this sentence: &#8220;I need this meeting to confirm ___.&#8221;</strong> If it&#8217;s a decision, know who makes it and what they need to hear to say yes. If it&#8217;s alignment, know exactly which known disagreement you&#8217;re there to settle.</p></li></ol><p>Do this and the meeting itself becomes almost boring, a formality confirming what you already built. That flat, boring feeling is what winning looks like. Krishna&#8217;s face never changed in that court, because nothing in that room was still being decided.</p><p><em>Next week: Choosing Your Battles, why the most strategic word in the language is &#8220;no.&#8221;</em></p><p><em>This is part 4 of a 10-part series on the inner game of organizational life, drawn from the Mahabharat. Subscribe to get one episode every Thursday, one battle at a time.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[When CPU Says Everything Is Fine]]></title><description><![CDATA[3B: Bit By Byte &#183; Season 01 &#183; GitHub August 17 &#183; Chapter 03 &#183; Capacity is whichever resource runs out first.]]></description><link>https://blog.mokshesh.com/p/when-cpu-says-everything-is-fine</link><guid isPermaLink="false">https://blog.mokshesh.com/p/when-cpu-says-everything-is-fine</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Thu, 03 Sep 2026 06:20:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!c7hQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.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_!c7hQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c7hQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!c7hQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!c7hQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!c7hQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c7hQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1614516,&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://blog.mokshesh.com/i/213952878?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.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_!c7hQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!c7hQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!c7hQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!c7hQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa877dc89-3b58-4d01-a0c8-00268abe5f7b_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Picture a restaurant on its busiest night. Walk into the kitchen and everything looks calm. The chefs are moving at maybe 40% of what they can do. Nobody is sweating, nothing is on fire, the line is not backed up. If you managed only by looking at the kitchen, you would conclude the restaurant has plenty of room to spare.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Now walk out to the front. There are 200 people waiting at reception. There is exactly one host, and the host can seat one party at a time. The line is out the door and around the corner.</p><p>The kitchen graph is green. The restaurant is failing.</p><p>Nothing about the kitchen is wrong. The measurement is honest. The chefs really are at 40%. But the number you are staring at has almost nothing to do with the thing that is actually limiting the restaurant tonight. The bottleneck is the host, and no dashboard in the kitchen will ever show it to you.</p><p>This is the whole idea of this chapter, and it is one of the most useful mental models the August 17 incident hands us:</p><p><strong>CPU is not capacity. Capacity is whichever resource runs out first.</strong></p><h3><strong>The principle, stated plainly</strong></h3><p>We tend to talk about a service being &#8220;at capacity&#8221; as if capacity were one number. It is not. A running service depends on a whole set of resources at once. CPU. Memory. Open connections. Network bandwidth. File descriptors. Concurrency slots in a proxy. Slots in a queue. Threads in a pool.</p><p>Your effective capacity is not the average of those. It is the <em>minimum</em>. You can do at most as much work as your most-exhausted necessary resource allows, and not one request more. Everything else can be sitting idle at 40% and it will not help you, in the same way that empty tables do not help when there is nobody free to seat people.</p><p>So &#8220;are we at capacity?&#8221; is the wrong question. The better one is: <strong>which resource are we about to run out of first, and are we even watching it?</strong></p><h3><strong>Translating this to your world</strong></h3><p>You have almost certainly lived the green-graph version of this.</p><p>An incident is happening. Users are seeing errors. And you are looking at a CPU chart that is calm, a memory chart that is calm, and you are thinking: the box is fine, so it cannot be us. Meanwhile the thing that is actually saturated is a connection pool, or a downstream rate limit, or the number of requests a proxy will hold at once. It never showed up on the charts you happened to open, so for the first twenty minutes it did not exist to you.</p><p>CPU gets this starring role for a boring reason: it is easy to measure and it is on every dashboard by default. Ease of measurement is not the same as relevance to the bottleneck. That gap is where outages hide.</p><p>There is a second half to this that is worth slowing down on, because it is where the incident gets its teeth. It has to do with concurrency, and how it grows even when nothing about your traffic changes.</p><h3><strong>Concurrency, and why it grows when you are not looking</strong></h3><p>Concurrency is just the number of requests in flight at the same instant. Not requests per second, which counts how fast they arrive. Concurrency counts how many are sitting inside your system right now, still being worked on.</p><p>Here is the part that surprises people. Concurrency can climb even when your request rate is perfectly flat.</p><p>Think about it with a mental picture. Suppose 1,000 requests arrive every second, and each one normally finishes in 100 milliseconds. At any given instant, roughly 100 of them are in flight. That is your concurrency. Comfortable.</p><p>Now something downstream slows down, and each request starts taking 1 second instead of 100 milliseconds. The arrival rate has not changed at all. Still 1,000 per second. But now each request lingers ten times longer, so roughly 1,000 of them are in flight at once. Your concurrency went up 10x, and your traffic did not move an inch.</p><p>That relationship has a name. In plain language: <strong>concurrency is roughly the arrival rate multiplied by how long each request takes.</strong> (People call this Little&#8217;s Law.) You do not need the math. You need the intuition: when latency rises, concurrency rises with it, silently, for free, without any new users showing up. Slowness quietly consumes concurrency.</p><p>And concurrency is exactly the kind of resource that has a hard ceiling. A proxy will only hold so many requests at once. When it hits that number, it does not run hot on CPU. It just refuses, or queues, or stalls.</p><h3><strong>GitHub says</strong></h3><p>Here is what we actually know, kept strictly to the record.</p><p>GitHub reported that during the August 17 incident an Istio sidecar reached its concurrency limit. It also reported that the autoscaling policy was configured around the host service rather than the sidecar&#8217;s own resource limits.</p><p>Read those two sentences together and the restaurant snaps into focus. The autoscaler was watching the kitchen. The bottleneck was the host. The scaling policy was pointed at the application, and the resource that actually ran out was the concurrency ceiling of the proxy sitting beside it.</p><p>Notice what this is <em>not</em>. The autoscaler was not broken. As far as the evidence tells us, it did exactly what it was configured to do. It looked at its metric, saw a healthy number, and correctly decided not to add capacity. A rational decision, made on an honest measurement, of the wrong thing. That is a far more unsettling failure than a bug, because the system was working as designed and still walked straight into the wall.</p><p>That gives us the question this whole chapter is really about:</p><p><strong>Are we scaling on what is easy to measure, or on what actually limits throughput?</strong></p><p>What we do <em>not</em> know, and will not pretend to: the exact numbers, the specific thresholds, or why the policy was pointed where it was. GitHub&#8217;s report does not say, so neither do we. The shape is what we are after, and the shape is clear enough.</p><h3><strong>Let&#8217;s experiment</strong></h3><p>The honest way to trust a claim like &#8220;the autoscaler watched the wrong thing&#8221; is to build the smallest system where it happens on purpose, and watch it fail.</p><p>Before the code, one last translation, because every number below is that scene with instruments attached. The kitchen is the service and the chefs at 40% are its CPU. The one host at the door is the proxy with its concurrency limit. The line out the door is requests in flight. And the manager who decides whether to call in more staff, by glancing only at the kitchen, is the autoscaler.</p><p>So I built exactly that. It is small enough to run on a laptop, and it ships with this chapter (link at the end of the section). Same Client -&gt; Proxy -&gt; Service as the last chapter, with two changes that make this one&#8217;s point:</p><pre><code><code>Client (flat rate)  -&gt;  Proxy (concurrency limit)  -&gt;  Service (getting slower)</code></code></pre><p>The <strong>Client</strong> is now open-loop: it fires at a fixed arrival rate, 1,000 requests per second, and never slows down no matter how long requests take. That is the whole setup. The arrival rate is held flat all run, so any rise in concurrency comes from latency alone, not from more traffic.</p><p>The <strong>Proxy</strong> enforces a concurrency limit of 100 per replica, and an <strong>autoscaler</strong> can add replicas to raise that ceiling. The autoscaler reads one metric several times a second and applies the ordinary scaling rule: if the metric is above target, add capacity.</p><p>The <strong>Service</strong> is healthy, and I make it slower on purpose, step by step: 50ms per request, then 100, then 200, then 400. That is the dependency degrading, each order taking longer to plate.</p><p>One measurement note before the tables, because a reader who sees <code>Svc CPU 40%</code> will reasonably assume it was measured. It was not. Service CPU is the one modeled number, not a measured one, because real per-request CPU is too noisy to ship a reproducible result. The model is deliberately simple and stated in the code: CPU tracks the real work the service actually completes, so when the proxy caps throughput, CPU falls with it. Everything else, the in-flight counts, the rejections, and the replica counts the autoscaler settles on, comes straight from the run. And the direction is the part that matters: In this experiment, rising latency never raises CPU, so a CPU-watching autoscaler cannot be provoked into scaling, no matter how bad things get.</p><p>Two column notes as well. <strong>Offered</strong> is the average concurrency the load implies, arrival rate times latency. <strong>In-flight</strong> is the measured <em>peak</em>, which sits a little above that average because the open-loop client fires in small bursts rather than a perfectly smooth trickle.</p><p>First run, the autoscaler watches service CPU. Here is the actual output:</p><pre><code><code>Autoscaler watches SERVICE CPU
Latency  Offered  In-flight  Replicas  Svc CPU  Reject
 (svc)   conc     peak       (scaled)  (model)  rate
 50ms    50       60         1         40%      0%
 100ms   100      100        1         37%      8%
 200ms   200      100        1         19%      51%
 400ms   400      100        1         11%      74%</code></code></pre><p>Read it top to bottom. The arrival rate never moved. But the Offered column climbs 50, 100, 200, 400, exactly as Little&#8217;s Law says it must. In-flight requests press against the proxy&#8217;s limit of 100 and stop there, because the proxy cannot admit the 101st request concurrently. And service CPU, the one number the autoscaler is watching, does not rise. It falls: 40%, 37%, 19%, 11%. The capped service is completing less real work per second while the overflow piles up at the door, so it looks <em>more</em> idle exactly as the outage gets worse. The autoscaler sees a healthy, falling number, holds at one replica, and by the last row is turning away almost three of every four requests.</p><p>Green CPU, failing service, and an autoscaler doing its job perfectly on an honest measurement of the wrong thing.</p><p>Now change one thing. Point the same autoscaler at proxy concurrency instead of CPU, and run the identical experiment:</p><pre><code><code>Autoscaler watches PROXY CONCURRENCY
Latency  Offered  In-flight  Replicas  Svc CPU  Reject
 (svc)   conc     peak       (scaled)  (model)  rate
 50ms    50       60         1         40%      0%
 100ms   100      110        2         40%      0%
 200ms   200      210        3         40%      0%
 400ms   400      410        5         40%      0%</code></code></pre><p>Same load, same slowdown, same scaling rule. The only thing we changed was what the autoscaler could see. But now the signal tracks the resource that actually saturates, so as concurrency climbs the autoscaler grows from 1 replica to 5, capacity keeps pace with the in-flight count, CPU holds near its 40% baseline, and nothing is rejected. The manager finally added hosts, because they were finally watching the door.</p><p><span>The code is </span><a href="https://github.com/moksheshd/experiments/tree/main/3b-bit-by-byte/season-01-github-august-17/03-autoscaling-blind-spot">in the season repo on GitHub</a><span>, under </span><code>03-autoscaling-blind-spot/</code><span>. Run </span><code>go run ./minimal</code><span> for the bare blind spot and one plain table, </span><code>go run .</code><span> for the full side-by-side run above, or </span><code>go run ./tui</code><span> to dial the latency yourself and toggle the autoscaler's signal live: watch CPU-watching do nothing while the reject bar climbs, then press one key to switch to concurrency and watch the replicas jump and the failures vanish. The reasoning stands on its own too: capacity is set by the first resource to run out, concurrency is a resource, and you cannot scale on a signal you never measured.</span></p><h3><strong>Next in 3B: Bit By Byte</strong></h3><p>There is a loose thread I left dangling. When requests start stalling and failing, the most natural thing in the world happens: everyone tries again. Retries are supposed to make systems more reliable. On August 17 they helped turn a constrained proxy into a much larger outage.</p><p>Chapter 4, <strong>When Retries Become the Outage.</strong> How the thing built to save you becomes the fuel, and what you do about it.</p><p>If you want the next question in your inbox when it lands, subscribe. That is the whole ask.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[The Proxy Beside Your Application]]></title><description><![CDATA[3B: Bit By Byte &#183; Season 01 &#183; GitHub August 17 &#183; Chapter 02 &#183; Your app can sit at 35% CPU and still be drowning.]]></description><link>https://blog.mokshesh.com/p/the-proxy-beside-your-application</link><guid isPermaLink="false">https://blog.mokshesh.com/p/the-proxy-beside-your-application</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Sun, 30 Aug 2026 02:25:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_LKL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.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_!_LKL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_LKL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!_LKL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!_LKL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!_LKL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_LKL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1570297,&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://blog.mokshesh.com/i/213309680?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.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_!_LKL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!_LKL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!_LKL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!_LKL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9c09eab-71e5-4439-be7b-96092bcd936b_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The dashboard is green. Picture the moment. An incident channel is on fire. Requests are failing. Customers are complaining. And you, half-panicked, pull up the metrics for the service everyone is blaming.</p><p>CPU: 35%. Memory: comfortable. Latency inside the application code: fine. The health check is passing. By every number you have been trained to trust, this service is healthy.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>And yet a large fraction of the traffic aimed at it never gets a clean answer.</p><p>This is the moment a lot of engineers (me included, more than once) start to doubt their own tools. The graphs say one thing, reality says another, and it is almost always because you are measuring one resource while a different one ran out. In the August 17 GitHub incident, one of the critical limits was not in the application at all. It was in the proxy sitting beside it.</p><p>Let me state the principle before I unpack it, because the whole chapter hangs on this one sentence.</p><p><strong>The proxy beside your workload is part of your application&#8217;s capacity.</strong></p><p>If you only remember one thing, remember that. Now let&#8217;s earn it.</p><h3><strong>GitHub says</strong></h3><p>I want to stay honest about what is documented and what is me reasoning. So, the facts first.</p><p>GitHub&#8217;s <a href="https://www.githubstatus.com/incidents/zkxwbgr0cnmx">incident report</a> states that the immediate cause was network saturation on load balancers in Central US after a new traffic peak, and that an Istio sidecar reached its concurrency limit. It also says autoscaling did not react correctly, because the scaling policy watched the host service rather than the sidecar&#8217;s limits.</p><p>That is the primary evidence for this chapter. Two phrases do the heavy lifting: <code>Istio sidecar</code> and <code>concurrency limit</code>. Everything else I write here is either general mechanism or an experiment. I will keep the buckets separate.</p><h3><strong>We can reason about: what a sidecar actually is</strong></h3><p>Here is the part that is safe to reason about, because it is how service meshes work in general, not a claim about GitHub&#8217;s private setup.</p><p>First, two words that get used interchangeably and should not be.</p><p><strong>Istio is the control plane.</strong> It is the brain that holds the rules. Which service can talk to which, what the timeouts are, how many concurrent requests are allowed, how traffic gets routed and retried. Istio manages the mesh&#8217;s configuration and policy and hands it down; it is not the thing sitting in the request path itself.</p><p><strong>Envoy is the data plane.</strong> It is the proxy that actually sits in the request path and enforces the rules Istio handed it. Every real request flows through Envoy. Istio writes the law, Envoy is the officer on the road.</p><p>A useful compression: <strong>Istio decides the rules, Envoy handles the traffic.</strong></p><p>Now the sidecar pattern. In Kubernetes, a &#8220;pod&#8221; can hold more than one container. A common Kubernetes sidecar pattern puts the Envoy proxy in the <em>same pod</em> as the application container. They share a network namespace, so from the application&#8217;s point of view the proxy is basically localhost.</p><p>The consequence is quiet but important: your application usually does not receive requests directly. Inbound traffic hits the Envoy proxy first, then Envoy forwards it to your app. Outbound traffic leaves your app, hits Envoy, then goes to the world.</p><pre><code><code>                 pod
        +-----------------------+
Client -&gt; [ Envoy proxy ] -&gt; [ Your app ]
        +-----------------------+
</code></code></pre><p>Why add a whole extra network hop next to every service? Because that proxy gives you routing, connection pooling, mutual TLS, retries, timeouts, and consistent telemetry, all without changing your application code. You get platform-level traffic behavior for free from the app&#8217;s perspective.</p><p>But &#8220;free from the app&#8217;s perspective&#8221; is exactly the trap.</p><p>That proxy is a real process. It has its own memory. Its own connection pool. Its own CPU. And its own <strong>concurrency limit</strong>: a cap on how many requests it will handle in flight at the same time.</p><p>Concurrency is worth defining precisely, because it is not the same as requests per second. Requests per second is a rate: how many arrive each second. Concurrency is how many are <em>simultaneously in flight</em> right now, still waiting for a response. If requests take 100 milliseconds, a proxy at 1,000 requests per second is holding about 100 in flight at once. If something downstream slows and each request now takes 1 second, that same 1,000 requests per second means about 1,000 in flight. The arrival rate did not change. The concurrency went up 10x.</p><p>The relationship is simple: concurrency is roughly throughput times latency (concurrency &#8776; throughput &#215; latency). Same arrival rate, 10x the latency, roughly 10x the in-flight work. That single fact is why a small slowdown downstream can saturate a proxy that was comfortable a moment ago.</p><p>That is the mechanism to hold onto when reading GitHub&#8217;s line that an Istio sidecar reached its concurrency limit. Here is the shape of the failure, reasoned generally. A proxy with a concurrency limit of, say, 1,000 is perfectly fine at 100 in flight. Then latency creeps up somewhere downstream. In-flight count climbs: 300, 600, 900, 1,000. Now the proxy is at its limit. Additional requests may be rejected or forced to wait, depending on how that limit is enforced.</p><p>And the application behind that proxy? It is still at 35% CPU. It never even saw those requests. It is idle and healthy while the doorway in front of it is jammed shut.</p><p>That is what I mean by &#8220;the proxy is part of your capacity.&#8221; Your capacity is not CPU. It is not memory. It is not replica count. Your effective capacity is constrained by the first necessary resource to reach its limit, and that resource can be any of:</p><ul><li><p>Application CPU</p></li><li><p>Application memory</p></li><li><p>Database connections</p></li><li><p>Thread pools</p></li><li><p>Network connections</p></li><li><p>Proxy concurrency</p></li><li><p>Queue depth</p></li></ul><p>Application CPU is only one entry on that list. Proxy concurrency is another. On August 17, per GitHub, the sidecar&#8217;s concurrency limit was one of the limits the system could not scale past. The durable question to leave with is not &#8220;how does Istio work&#8221; but &#8220;which of these invisible limits is closest to the edge in <em>my</em> system, and am I graphing it?&#8221;</p><h3><strong>We don&#8217;t know</strong></h3><p>I want to be careful here, because this is the exact place where it is tempting to invent an architecture.</p><p>I do not know GitHub&#8217;s actual concurrency numbers, how their sidecars were deployed, what the limits were set to, or how their pods were laid out. I do not know whether the picture above matches their topology at all. GitHub&#8217;s report tells us a sidecar reached a concurrency limit. It does not hand us the diagram, and I am not going to draw one for them.</p><p>What I <em>can</em> do is build a tiny system that has the same shape, and watch the behavior happen with my own eyes.</p><h3><strong>Let&#8217;s experiment</strong></h3><p>Before the code, hold one picture in your head, because every number below is that picture with instruments attached.</p><p>Think of a room with a fire-code capacity of fifty, and one doorway with someone counting people through it. Below fifty, everyone walks straight in. At fifty, the next person waits outside, or gets turned away, no matter how empty the room looks to the people already inside. The doorway is the proxy. Fifty is its concurrency limit. The people in the room are requests in flight, and the room itself is your service: it can feel half-empty while a crowd piles up at its one door.</p><p>So I built exactly that. It is small enough to run on a laptop, and it ships with this chapter (link at the end of the section). Three pieces:</p><pre><code><code>Client  -&gt;  Proxy (concurrency limit)  -&gt;  Service (healthy, fast)
</code></code></pre><p>The <strong>Service</strong> is deliberately boring and healthy. It does a tiny slice of work per request (20 milliseconds) and returns. Low load. It is not the villain, and that is the whole point.</p><p>The <strong>Proxy</strong> sits in front of it and enforces a hard concurrency limit: at most 50 requests in flight at once. Anything beyond that is rejected at the door. Envoy provides mechanisms for limiting concurrent requests. For the lab, I model the same constraint with a semaphore: a counting gate that allows only 50 requests to be in flight at a time. I am demonstrating the capacity mechanism, not reproducing Envoy&#8217;s internals.</p><p>The <strong>Client</strong> ramps up: 10 concurrent requests, then 30, then 60, then 120.</p><p>Then I watch what the service experiences and what the client experiences, side by side. Here is the actual output of one run:</p><pre><code><code>Client  Svc CPU  Svc peak  Proxy   Success
 conc   (model)  in-flight reject  rate
&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;
 10     7%       10        0       100%
 30     21%      30        0       100%
 60     35%      50        960     83%
 120    35%      50        6720    42%
</code></code></pre><p>Two things happen at once, and they are the whole chapter.</p><p>Below 50 concurrent, everything is green: the service load climbs with the client, no rejections, every request succeeds.</p><p>Push past 50 and the two stories split. The service&#8217;s in-flight count pins at 50 and never climbs again, because the proxy will not admit a 51st request: the room is full. Its load, and so its CPU, has a ceiling that the client cannot push past. But the client&#8217;s success rate falls off a cliff: 83% at 60 concurrent, 42% at 120. The proxy is turning the overflow away at the door, and the requests aimed at a perfectly healthy service simply never reach it.</p><p>One honest note on that table: service CPU is the one modeled number, not a measured one, because real per-request CPU is too noisy to ship a reproducible result. The model is deliberately simple: the service runs at 35% when it is handling its 50-request ceiling, and scales down from there. Everything else, the rejections, the success rate, the in-flight counts, is measured from the run. The ceiling is the part that matters, and the ceiling is real: the proxy caps how many requests ever reach the service.</p><p>That is the entire lesson, made physical. Two numbers telling opposite stories about the same system. The service says &#8220;I am at 35% and fine.&#8221; The client says &#8220;I am failing 58% of the time.&#8221; Both are true. The truth lives in the proxy, and nobody was looking at it.</p><p><span>The code is </span><a href="https://github.com/moksheshd/experiments/tree/main/3b-bit-by-byte/season-01-github-august-17/02-proxy-concurrency">in the season repo on GitHub</a><span>, under </span><code>02-proxy-concurrency/</code><span>. Run </span><code>go run ./minimal</code><span> for the bare mechanism and one plain table, </span><code>go run .</code><span> for the full instrumented run above, or </span><code>go run ./tui</code><span> to turn the load knob yourself and watch the service bar freeze at the limit while the client bar keeps climbing. Flip on </span><code>--queue</code><span> and the failures turn into latency instead of errors; raise </span><code>--service-ms</code><span> and throughput falls while the CPU ceiling holds, because the service can only ever clear about fifty requests per service-time. That last one is the earlier concurrency &#8776; throughput &#215; latency made live: at a fixed limit, faster requests mean more goodput and slower requests mean less, for exactly the same proxy.</span></p><h3><strong>Back to the incident</strong></h3><p>So when GitHub says a sidecar reached its concurrency limit, this is the mechanism worth carrying: a proxy beside the workload has its own hard limits, independent of the application&#8217;s CPU, and when it saturates, the application can look perfectly healthy while the requests aimed at it fail.</p><p>Green dashboards are not proof of health. They are proof that the thing you graphed is healthy. The proxy beside your application deserves its own graph.</p><p>Which raises the obvious next question. If the app was fine and the proxy was the bottleneck, why didn&#8217;t autoscaling notice and add more capacity? Because autoscaling can only react to what it is told to watch, and it was watching the wrong thing.</p><h3><strong>Next in 3B: Bit By Byte</strong></h3><p>Chapter 3, <strong>When CPU Says Everything Is Fine.</strong> We follow the scaling signal that missed the real limit.</p><p>If you want the rest of this investigation as it lands, one question at a time, subscribe and follow along.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[What Happened? Learning to Read an Outage]]></title><description><![CDATA[3B: Bit By Byte &#183; Season 01 &#183; GitHub August 17 &#183; Chapter 01 &#183; The what is free. The why is the work.]]></description><link>https://blog.mokshesh.com/p/what-happened-learning-to-read-an</link><guid isPermaLink="false">https://blog.mokshesh.com/p/what-happened-learning-to-read-an</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Thu, 27 Aug 2026 19:28:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nC5s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.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_!nC5s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nC5s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!nC5s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!nC5s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!nC5s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nC5s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png" width="728" height="485.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:1697312,&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://blog.mokshesh.com/i/213041626?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.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_!nC5s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!nC5s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!nC5s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!nC5s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ab2434e-0fb8-4881-9c2a-13791fc6a854_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>At 13:28 UTC on August 17, 2026, GitHub.com started experiencing elevated errors and latency.</p><p>Issues and Pull Requests were affected. The APIs were affected. Actions was affected. Copilot was affected. Authentication was affected. But they did not all fail in the same way, and they did not all recover at the same time.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>By the time it was over, the clock read 7 hours and 47 minutes. That is the headline number, and it is the easy one. Anyone can read that number. Anyone can read the list of things that broke. The interesting question, the one that actually teaches you something, is not what broke. It is why it broke in that order, and what ran out first.</p><p>That question is what this whole season is about. In this first chapter I just want to lay out the map and teach you how to read it.</p><h3><strong>GitHub says</strong></h3><p>Let me be strict about sourcing, because that discipline is the entire point of 3B. Everything here is from GitHub&#8217;s own incident writeup and status page. When I say &#8220;GitHub says,&#8221; I mean it is documented by the people who were there. When I start reasoning, I will label it. When the evidence runs out, I will say &#8220;we don&#8217;t know.&#8221;</p><p>And I am going to stop at the symptoms. Not the causes. The causal chain is the rest of the season, and I refuse to hand it to you as one tidy paragraph you will have forgotten by tomorrow.</p><p>The incident ran 13:28 to 21:15 UTC: 7 hours and 47 minutes. In that window a lot of GitHub did not work. Issues and Pull Requests. The REST and GraphQL APIs. Actions. Copilot. Sign-in itself: SAML and OIDC, SCIM, Team Sync. At the peak, roughly one in five web and API requests were failing. For archive and raw content downloads, closer to one in two.</p><p>Recovery did not arrive all at once, and the staggering is the clue I want you to carry. Most services were back around 16:36 UTC. Actions dragged until about 18:03. And one service, the Copilot Token Service, did not fully recover until 21:02, hours after everything else. Same incident, wildly different recovery times. Sit with that gap. It is a question this season exists to answer.</p><p>That is the <em>what</em>, and I am leaving it there on purpose. GitHub&#8217;s report does explain the causal chain, and it is a good one. But I am deliberately not compressing it into a paragraph here. Each link in that chain raises a different systems question, and those questions are where the useful lessons live. Fold it all into one tidy summary and you will nod, feel informed, and learn nothing. So I am going to spend the chapters ahead pulling it apart one link at a time.</p><h3><strong>The lens</strong></h3><p>Here is the lens I want you to take from this chapter, stated plainly:</p><p><strong>A capacity driven outage rarely stays one failure. One constraint creates pressure somewhere else, and that pressure can become the next failure.</strong></p><p>Sometimes that constraint is literal exhaustion. Sometimes it is a concurrency limit, a queue boundary, or another imposed ceiling.</p><p>Notice the words &#8220;capacity driven.&#8221; Not every outage works this way. Plenty are caused by a bad deploy, a config mistake, an expired certificate, corrupted state, a routing error, a plain software defect, and for those, &#8220;what ran out&#8221; is the wrong question entirely. But when an incident is about capacity, it rarely stays a single failure, because an exhausted resource does not fail politely in place. It pushes load somewhere it was not expected, and that somewhere becomes the next thing to give.</p><p>So when I read a capacity related incident, I keep two questions running in a loop:</p><p>What constraint was hit? And what did that cause to give next? &#8220;What ran out?&#8221; is the shorthand I actually say in my head, as long as I remember that not every constraint is literal exhaustion.</p><p>August 17 mostly reads that way, though not entirely: a couple of its links are not simple exhaustion, and we will get to those honestly when we reach them. You do not have the pieces to trace the chain yet. That is the point of the chapters ahead. For now, practice the reading itself.</p><h3><strong>How to think about it</strong></h3><p>When you read an incident, yours or anyone else&#8217;s, hold three buckets separately and refuse to let them blur.</p><p><strong>1. What we know.</strong> What the evidence explicitly establishes. Timestamps, error rates, the named components. No interpretation yet.</p><p><strong>2. What we can reason about.</strong> The engineering mechanisms that could explain those observations. This is where you get to be clever, but honestly labeled: you are reasoning, not reporting.</p><p><strong>3. What we do not know.</strong> Where the public evidence stops. Naming the gap is not a weakness. It is the difference between someone who understands a system and someone who is performing understanding.</p><p>I want to get comfortable saying &#8220;we don&#8217;t know,&#8221; because otherwise reasoning quietly turns into storytelling.</p><p>Most of this chapter has lived in the first bucket on purpose. We build the evidence base before we build any theories on top of it.</p><h3><strong>A practice for this week</strong></h3><p>Find one incident report. GitHub&#8217;s, or your own team&#8217;s last postmortem, or any public one you can get your hands on.</p><p>One rule before you start: do not read the root cause section yet. Read the symptoms, then write down what you think the mechanism was, in your own words, before you look. Only afterward compare your hypothesis against what the report actually concluded. The gap between the two is the lesson. It is the difference between observation leading to hypothesis leading to evidence, and simply copying an answer out of a postmortem.</p><p>Read it once for the story. Then read it a second time with a pen. Next to every failure, ask: was something exhausted here, and if so, what? Connections? Concurrency? Memory? Queue capacity? Network flows? Regional capacity? And if nothing seems to have been exhausted, ask what other mechanism produced the failure: a bad deploy, a config change, an expired certificate, a logic bug. Do not stop at &#8220;the service was slow.&#8221; Slow because of what?</p><p>If you cannot name the mechanism, that is not a failure of the exercise. That is you finding an edge of the report, a place where the <em>what</em> is documented but the <em>why</em> is not. Mark it. Those edges are exactly where the interesting work starts.</p><h3><strong>The repo</strong></h3><p>Everything in 3B ships with runnable code, and Chapter 1 is no exception. In the season repo I keep the August 17 timeline as a small machine-readable file, plus a short worksheet script that walks you through it one event at a time and asks the only question that matters: what ran out here? It is the practice above, automated, and it is the seed the rest of the season&#8217;s lab grows from.</p><p>Clone it and follow along:</p><pre><code><code>git clone git@github.com:moksheshd/experiments.git
cd experiments/3b-bit-by-byte/season-01-github-august-17/01-reading-an-outage</code></code></pre><p>The repo: <a href="https://github.com/moksheshd/experiments">github.com/moksheshd/experiments</a></p><h3><strong>Next in 3B: Bit By Byte</strong></h3><p>We start pulling the first thread. GitHub names an Istio sidecar, a proxy that sits right next to the application, and most engineers have never really looked at it. Next, in Chapter 2, The Proxy Beside Your Application, we find out what that thing actually does, why it has a concurrency limit at all, and why watching the wrong signal to scale it can quietly set a fire.</p><p>Some of the questions ahead will sound embarrassingly basic. Why do we even need a proxy there? Why didn&#8217;t CPU go up? Why retry something that is already overloaded? Ask them anyway. Basic questions asked relentlessly, held strictly to what the evidence proves, are the whole method.</p><p>If you want to follow the whole teardown, subscribe and come along.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[Influence Is Built Before You Need It]]></title><description><![CDATA[Influence comes before authority, and it's built by understanding people, not persuading them.]]></description><link>https://blog.mokshesh.com/p/influence-is-built-before-you-need</link><guid isPermaLink="false">https://blog.mokshesh.com/p/influence-is-built-before-you-need</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Thu, 27 Aug 2026 08:09:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!W8Wb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.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_!W8Wb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W8Wb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!W8Wb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!W8Wb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!W8Wb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W8Wb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2687160,&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://blog.mokshesh.com/i/212964955?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.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_!W8Wb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!W8Wb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!W8Wb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!W8Wb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F956e4063-2f26-4708-8334-a5bdc560496a_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Krishna spends the entire war of Kurukshetra in the humblest job on the field.</p><p>He is not a king in this war. He carries no weapon; he has vowed not to fight. His role is <em>sarathi</em>, charioteer. He holds the reins while Arjuna shoots. On paper, he is staff, not line. He has no command, no soldiers of his own in the fight, no formal authority over anyone.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>And he may be the most influential figure on the entire field.</p><p>Kings defer to him. The outcome of the war bends around his judgment. The most important text in the tradition is a record of him talking to the man whose chariot he was driving. He moved everything, and he did it from a seat with no title.</p><h3><strong>The principle</strong></h3><p>We are taught that influence flows from authority: get the title, get the corner office, and then people will listen. It&#8217;s backwards. Authority tends to be granted to people who already have influence. The title is the lagging indicator. The influence came first.</p><p>And influence is not the same as persuasion. This is the part almost everyone gets wrong. We think being influential means being good at <em>convincing</em>: better arguments, sharper rhetoric, more compelling slides. But the influential don&#8217;t skip persuasion. They earn the right to barely need it. Persuasion sits downstream of understanding: they start from <em>&#8220;what matters to this person,&#8221;</em> not <em>&#8220;how do I convince them,&#8221;</em> so by the time they make the case, they&#8217;re already speaking to what the other side actually wants.</p><p>Krishna influenced everyone because he understood everyone: every warrior&#8217;s ego, every king&#8217;s fear, every fracture in every alliance. He didn&#8217;t out-argue people. He knew them.</p><h3><strong>The translation</strong></h3><p>Early in my career, at a contact-center company in late 2012, I was a regular engineer with no mandate to change anything. Back then, putting video into a contact center meant serious hardware: dedicated video gateways, multipoint units, specialized endpoints, and the licensing that rode on top. It was a capital decision, not a feature you just turned on.</p><p>Our VP of Marketing kept talking up a new thing called WebRTC: real-time video straight in the browser, no plugins, no special hardware. It was barely real yet; the first cross-browser video calls were only just happening. But something about it hooked me. Nobody assigned it to me. I taught myself the technology on my own time and built a rough proof-of-concept: a live call running between two browser tabs, no plugin installed, no hardware behind it. Then I wrote up how it could plug into what we already sold, without the hardware bill.</p><p>I didn&#8217;t walk into a room and argue for it. I showed people the thing working, framed in the terms each of them cared about: for marketing, the story they were already excited to tell; for engineering, less latency and server load; for leadership, a way to leapfrog a huge hardware investment. By the time I asked to lead the effort, there was almost nothing to persuade. That project became a differentiator in our sales pitches, and the title I&#8217;d been nowhere near, Module Leader, followed. The influence came first. The title just caught up.</p><p>Look around your organization at the people who move rooms without a title. The engineer whose opinion the VP quietly checks. The person two levels down whose &#8220;I&#8217;m not sure about this&#8221; can stall a launch. They are not louder or more senior. They have built an <em>architecture of influence</em>, and it rests on three things, none of which is a job level:</p><ul><li><p><strong>They understand what people want.</strong> Before they make a case, they already know what the other person is trying to protect, win, or avoid. So their &#8220;pitch&#8221; lands as <em>&#8220;here&#8217;s how this gets you what you need,&#8221;</em> not <em>&#8220;here&#8217;s why I&#8217;m right.&#8221;</em></p></li><li><p><strong>They are trusted with the truth.</strong> Influence compounds on reliability. The person who tells you the uncomfortable thing when it would be easier to flatter you becomes the person you can&#8217;t make a decision without.</p></li><li><p><strong>They give before they ask.</strong> Krishna served, literally held the reins, long before the moment his counsel decided the war. Influence is something you deposit before you withdraw.</p></li></ul><p>Notice what these share: each is something you do <em>before</em> you need it. You understand people before you need their support. You tell the truth before you need their trust. You give before you need their help. That is the architecture: influence built in advance.</p><p>The person chasing influence through authority says: <em>once I&#8217;m promoted, they&#8217;ll have to listen.</em> The person building influence says: <em>let me understand you so well that a title becomes a formality.</em> Only one of those compounds.</p><h3><strong>The practice</strong></h3><p>Pick one person whose support you&#8217;ll need for something that matters in the next few months. Before you ever make your case:</p><ol><li><p><strong>Write down what they actually want:</strong> the real thing they&#8217;re optimizing for, in their words, not yours. If you&#8217;re guessing, you don&#8217;t know them well enough yet. Have the conversation whose only goal is to find out.</p></li><li><p><strong>Do one useful thing for them with no ask attached.</strong> Share the context they&#8217;re missing, connect them to someone, take a small thing off their plate. Deposit before you withdraw.</p></li><li><p><strong>When you finally make your case, frame it in their terms.</strong> Not &#8220;here&#8217;s why I&#8217;m right.&#8221; Instead: &#8220;here&#8217;s how this gets you what you&#8217;re trying to get.&#8221;</p></li></ol><p>You&#8217;ll notice you barely have to persuade. That&#8217;s the point. Persuasion is the tax you pay for not having done this earlier.</p><p>The man with no title and no weapon moved the whole war. The influence came before the authority.</p><p><em>Next time: why the real conversation almost never happens in the meeting itself.</em></p><p><em>This is part 3 of a 10-part series on the inner game of organizational life, drawn from the Mahabharat. Subscribe to get one episode every Thursday, one battle at a time.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[Reading the Battlefield]]></title><description><![CDATA[Politics is terrain, not warfare. Learn to read the ground before you fight on it.]]></description><link>https://blog.mokshesh.com/p/reading-the-battlefield</link><guid isPermaLink="false">https://blog.mokshesh.com/p/reading-the-battlefield</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Thu, 20 Aug 2026 11:00:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!B1xp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.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_!B1xp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B1xp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!B1xp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!B1xp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!B1xp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B1xp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2355696,&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://blog.mokshesh.com/i/211982249?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.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_!B1xp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!B1xp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!B1xp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!B1xp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c12a17-bedc-4bf8-b034-8aee36e9531d_1536x1024.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 buttonBase-GK1x3M"><svg aria-hidden="true" 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" class="icon-noB79L"><g><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 buttonBase-GK1x3M"><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 icon-noB79L"><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>Before the war, both sides go to Krishna. Duryodhana and Arjuna arrive at Krishna&#8217;s chamber at nearly the same moment. He is asleep. Duryodhana, proud, takes the seat near Krishna&#8217;s head. Arjuna waits humbly at his feet. When Krishna wakes, his eyes fall on Arjuna first, the one at his feet, and he offers each of them a choice: on one side, his entire army, the mighty Narayani Sena. On the other, Krishna himself, alone, who will not lift a single weapon.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Duryodhana can hardly believe his luck. He picks the army. Arjuna picks the unarmed man.</p><p>On the surface, Duryodhana had made the shrewder choice. He got the <em>countable</em> thing: thousands of soldiers. Arjuna got one man who had vowed not to fight. But Arjuna had read the battlefield correctly, and Duryodhana had not. He had confused the <em>visible</em> source of power with the <em>actual</em> one.</p><h3><strong>The principle</strong></h3><p>Most people treat organizational politics as warfare, a thing you win by fighting harder, pushing more, out-arguing the other side. It isn&#8217;t. Politics is terrain. It is the shape of the ground you&#8217;re standing on: where the power actually sits, what each person is really trying to protect, and which relationships actually matter when a decision gets made.</p><p>You cannot out-fight bad terrain. An army on high ground beats a better army in the valley. And in an organization, the person who has read the terrain will beat the person who simply came prepared to fight. The one who knows that the &#8220;decision-maker&#8221; defers to someone three doors down, that the loud objection in the meeting is theater and the real veto came by DM an hour earlier.</p><p>Duryodhana counted soldiers. Arjuna read the field.</p><h3><strong>The translation</strong></h3><p>A few years ago, I pushed to break our main system apart into smaller pieces. When we first entered the market it had been one simple monolith, and that was the right call: it gave us speed, we shipped fast. But two or three years in, the client base had grown and the same design was creaking. Performance was slipping, and the code had turned into a tangle nobody wanted to touch.</p><p>I was sure I was right, and I had the data to prove it: the bottlenecks, the graphs, the whole case. I walked into the room expecting the argument to win, because the argument was correct.</p><p>It went nowhere. The senior architects and a few of the team looked at my charts, nodded, and quietly did not move. I pushed harder. More data, cleaner slides, the same polite nothing.</p><p>What I had misread wasn&#8217;t the technology. It was what the people in that room were actually protecting. I thought they were defending the old design. They were defending simplicity: one codebase, one deployment, one place to hold the whole system in your head, and a way of working they had gotten fast at. The new AI coding assistants reinforced that advantage. They could read the whole thing at once and generate code against it easily, and breaking it into services put that simplicity at risk. The decision was never going to be settled by whoever had the best benchmark. It was going to be settled by what those senior people were unwilling to give up.</p><p>Once I understood that, I stopped arguing performance. I started answering the thing they actually cared about. I took one small, low-risk piece, the report-generation logic, pulled it out into its own service, and showed it could be built with the same AI tools, deployed on its own, and run without the mess they were bracing for. That one working example did what my benchmarks never could. It didn&#8217;t win everyone over, but it earned me enough room to take the same approach to the core logic that mattered most.</p><p>I had spent weeks aiming at the wrong target.</p><p>Every organization has two maps. There is the org chart, the <em>ranbhoomi</em> as it&#8217;s officially drawn, and there is the real map of how things actually get decided. The two are rarely the same. Reading the battlefield means learning the second one.</p><p>Ask, before any move:</p><ul><li><p><strong>Where does power actually sit?</strong> Titles tell you where authority is <em>supposed</em> to be. Watch instead for whose name gets invoked, whose small objection stops a project, whose approval people seek before they seek the official one.</p></li><li><p><strong>What is each person actually trying to protect?</strong> Not the stated goal. The real one. The manager guarding headcount. The peer whose priorities are threatened by your project. Most people make sense once you know what they&#8217;re really trying to hold on to.</p></li><li><p><strong>Which relationships actually matter?</strong> Some people can stop a decision cold. Most can&#8217;t, however friendly they seem. Back the wrong one and you&#8217;re counting on support that was never really there.</p></li></ul><p>None of this is cynical. It&#8217;s just how things actually work. You can insist the org chart is reality all you want. The people making the real decisions won&#8217;t notice.</p><p>Krishna, unarmed, standing in Arjuna&#8217;s chariot, turned out to matter more than an army. Not because he fought, but because he could see the whole field and the people on it, the judgment no number of soldiers can buy. The way I read it, that is why one unarmed man mattered more than Duryodhana&#8217;s thousands.</p><h3><strong>The practice</strong></h3><p>Draw your organization&#8217;s <em>real</em> map on paper. For the decision you care about most right now:</p><ol><li><p><strong>Name the official decision-maker.</strong> Then ask: who do <em>they</em> check with before they decide? That person may have more practical influence than the org chart suggests.</p></li><li><p><strong>For each key player, write one line:</strong> &#8220;What do they actually need to protect or win here?&#8221; If you can&#8217;t answer it, you don&#8217;t understand the terrain yet, so go find out before you move.</p></li><li><p><strong>Mark the relationships that can stop this.</strong> Who, if they said no, ends it? Those are the ones that matter. The rest is noise.</p></li></ol><p>Keep it private. Redraw it every quarter, because terrain shifts. But once you can see the real map, you&#8217;ll stop fighting uphill by accident.</p><p><em>Next week: How the unarmed man in the chariot became the most influential figure in the war.</em></p><p><em>This is part 2 of a 10-part series on the inner game of organizational life, drawn from the Mahabharat. Subscribe to get one episode every Thursday, one battle at a time.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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[Manobhoomi Before Ranbhoomi]]></title><description><![CDATA[Every battle is fought twice: once in the mind, once in the room.]]></description><link>https://blog.mokshesh.com/p/manobhoomi-before-ranbhoomi</link><guid isPermaLink="false">https://blog.mokshesh.com/p/manobhoomi-before-ranbhoomi</guid><dc:creator><![CDATA[Mokshesh Dafariya]]></dc:creator><pubDate>Thu, 13 Aug 2026 12:16:30 GMT</pubDate><content:encoded><![CDATA[<p>On its first morning, the greatest war in the Mahabharat stops before it starts, because of a man who cannot lift his bow.</p><p>Two armies stand ready on the field of Kurukshetra. The conches have been blown. And Arjuna, the finest archer of his age and the warrior everyone came to see, asks his charioteer to pull the chariot into the gap between the armies. He looks across at the men he is about to fight: his teachers, his cousins, the grandfather who raised him. And he sits down. His bow, the Gandiva, slips from his hand. &#8220;I will not fight,&#8221; he says.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Nothing has happened yet. Not a single arrow has flown. The battle that stops Arjuna is not the one in front of him. It is the one inside him. And so before the war of Kurukshetra can begin, another war has to be fought first: in the space of one conversation, in the mind of one man. That conversation is the Bhagavad Gita. The way I read it: the outer war cannot start until the inner one is settled. What Krishna actually said (the argument that got Arjuna to stand back up) fills eighteen chapters, and parts of it will get their own episodes later in this series.</p><p>The line that started this whole series for me did not come from the Gita. It came from Shakuni.</p><p>I was watching a clip from the TV <em>Mahabharat</em> one night. Shakuni, the great schemer, was coaching Duryodhana before the war:</p><blockquote><p><em>Ranbhoomi mein khelne se pehle, manobhoomi mein khela jaata hai.</em> </p><p>Before the game is played on the battlefield, it is played on the field of the mind.</p></blockquote><p>Notice who says it. Not Krishna, not a sage, but the man who engineered the war itself, telling his nephew that the battle is decided before it is fought. Both sides of Kurukshetra knew this. Shakuni used it to scheme. Arjuna, the better warrior, had to learn it in the middle of the field. And to be clear about where the words come from: the Mahabharat gave me Arjuna. The television adaptation gave me the phrase.</p><p><em>Ranbhoomi</em> is the field of war: the meeting, the review, the pitch. <em>Manobhoomi</em> is the field of the mind: where you meet all of it before it happens. Mind first. Room second.</p><h3><strong>The night before</strong></h3><p>I learned this the long way.</p><p>A few years ago, I was working at a company that builds software for pharmaceutical manufacturing. Two days before a major release, we sat in a pre-deployment meeting where people senior to me pushed to skip validation steps. A key client had been promised a date, and the date was winning. In that industry, validation isn&#8217;t paperwork. Our software sat close enough to drug manufacturing that a bad release doesn&#8217;t just break a dashboard. It can touch patient safety.</p><p>I was one of the least senior people in that room. And the only reason I could open my mouth is that I had already been in that room the night before: alone, at my desk. I had played the meeting forward. I knew someone would ask <em>how long will it really take</em>, so I had worked out the actual numbers instead of the scary ones. And I had decided, in advance, who I was going to be when the pushback came: not angry, not apologetic, just unwilling to move on this one thing.</p><p>The meeting was heated. At one point someone said, more or less: &#8220;If we slip three days, we lose the client.&#8221; I heard myself answer, evenly: &#8220;If we ship this unvalidated, we can lose a lot more than a client.&#8221; Not courage: I had already answered that exact sentence the night before. For me, the meeting was a rerun. We did the validation. It cost us three days, and it caught two defects that would have gone straight into production.</p><p>I did not know the word for it then. I found Shakuni&#8217;s line years later. But that night at my desk was the <em>manobhoomi</em>. The meeting was just the <em>ranbhoomi</em>.</p><h3><strong>Every battle is fought twice</strong></h3><p>For most of my career, I thought preparing for a big meeting meant preparing the material. Polish the deck. Rehearse the opening. Get the numbers right. And then I&#8217;d walk in, someone would push back in a way I hadn&#8217;t imagined, and all that polish wouldn&#8217;t help me at all.</p><p>You know the feeling that comes next. You walk out, and an hour later, in the elevator or on the ride home, the perfect answer shows up. We joke about it, but think about what it means: the answer was in you the whole time. Your mind just did its real work an hour too late. It fought the battle after the battle was over.</p><p>Most people who seem &#8220;quick on their feet&#8221; in big meetings are not improvising as much as it looks. They&#8217;ve done what I did at my desk that night: imagined the pushback, felt the discomfort early, chosen their response. In the room, nothing is happening to them for the first time.</p><p>And notice what Arjuna&#8217;s problem was. It was never skill. He could out-shoot every man on that field. What he hadn&#8217;t done was settle, inside himself, why he was there and who he intended to be. All the skill in the world can&#8217;t make up for that. That part of the battle can only be fought in one place, and it isn&#8217;t the field.</p><p>Every battle is fought twice. The first time is quiet, invisible, and unglamorous. It&#8217;s the one that decides the second.</p><h3><strong>The Monday practice</strong></h3><p>For the next high-stakes moment on your calendar, spend ten minutes the day before on just this:</p><ol><li><p><strong>Name the outcome you actually want.</strong> Not the agenda item, the real one. &#8220;I want them to leave trusting the plan&#8221; is an outcome. &#8220;Present the roadmap&#8221; is not.</p></li><li><p><strong>Play the room forward once.</strong> Who pushes back? What&#8217;s the hardest thing someone could say to you? Say your answer out loud, badly. Then say it again, better.</p></li><li><p><strong>Decide who you&#8217;ll be if it goes wrong.</strong> Calm? Curious? Firm? Pick it now, because you won&#8217;t get to pick it then.</p></li></ol><p>That&#8217;s it. Ten minutes on the <em>manobhoomi</em>, and you walk into the <em>ranbhoomi</em> having already been there once.</p><p>Arjuna picked his bow back up only after the inner war was won.</p><p>The meeting is tomorrow. The battle starts tonight.</p><p><em>Next week: Reading the Battlefield. Why the ground you&#8217;re fighting on matters more than how hard you fight.</em></p><p><em>This is part 1 of a 10-part series on the inner game of corporate life, drawn from the Mahabharat. Subscribe to get one episode every Thursday, one battle at a time.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.mokshesh.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></channel></rss>