<?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[Khola.Blog: Post-Human Engineering]]></title><description><![CDATA[Software engineering after code generation stops being the hard part.]]></description><link>https://www.khola.blog</link><image><url>https://substackcdn.com/image/fetch/$s_!5Ait!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1245951-7811-417f-9bac-7e8c055ac43e_1280x1280.png</url><title>Khola.Blog: Post-Human Engineering</title><link>https://www.khola.blog</link></image><generator>Substack</generator><lastBuildDate>Mon, 29 Jun 2026 16:32:59 GMT</lastBuildDate><atom:link href="https://www.khola.blog/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Nitin Khola]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[nitinkhola@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[nitinkhola@substack.com]]></itunes:email><itunes:name><![CDATA[Nitin Khola]]></itunes:name></itunes:owner><itunes:author><![CDATA[Nitin Khola]]></itunes:author><googleplay:owner><![CDATA[nitinkhola@substack.com]]></googleplay:owner><googleplay:email><![CDATA[nitinkhola@substack.com]]></googleplay:email><googleplay:author><![CDATA[Nitin Khola]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Code Review Fatigue and The New Seniority]]></title><description><![CDATA[AI did not remove the hard part of software engineering. It moved it from writing code to proving the code is worth trusting.]]></description><link>https://www.khola.blog/p/code-review-fatigue-and-the-new-seniority</link><guid isPermaLink="false">https://www.khola.blog/p/code-review-fatigue-and-the-new-seniority</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Fri, 26 Jun 2026 15:56:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8WM3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>The Verification Tax</strong></h2><p>I think the fight over AI coding is less about taste than people admit.</p><p>At one pole, Andrew Kelley bans LLM-generated contributions from Zig. <strong>His argument is economic.</strong> Maintainers do not have infinite review time, and a low-effort AI pull request spends the scarcest resource in the project: the attention of someone who can actually tell whether the patch belongs there.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog: Post-Human Engineering! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8WM3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8WM3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 424w, https://substackcdn.com/image/fetch/$s_!8WM3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 848w, https://substackcdn.com/image/fetch/$s_!8WM3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 1272w, https://substackcdn.com/image/fetch/$s_!8WM3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8WM3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png" width="700" height="463.9423076923077" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/facf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:965,&quot;width&quot;:1456,&quot;resizeWidth&quot;:700,&quot;bytes&quot;:695415,&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://www.khola.blog/i/203565127?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.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_!8WM3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 424w, https://substackcdn.com/image/fetch/$s_!8WM3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 848w, https://substackcdn.com/image/fetch/$s_!8WM3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 1272w, https://substackcdn.com/image/fetch/$s_!8WM3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffacf549a-cf8b-49e3-a367-7898f8212038_1678x1112.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Courtesy: Startup Fortune</figcaption></figure></div><p>At the other pole, Andrej Karpathy gave us the language of vibe coding, and then the industry took the phrase as permission to stop touching the keyboard. The emotionally honest version of that position is seductive: if the agent can produce the code, why keep paying the human cost of typing it?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!33oj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!33oj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 424w, https://substackcdn.com/image/fetch/$s_!33oj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 848w, https://substackcdn.com/image/fetch/$s_!33oj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 1272w, https://substackcdn.com/image/fetch/$s_!33oj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!33oj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png" width="1456" height="491" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:491,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:232745,&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;:false,&quot;internalRedirect&quot;:&quot;https://www.khola.blog/i/203565127?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.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_!33oj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 424w, https://substackcdn.com/image/fetch/$s_!33oj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 848w, https://substackcdn.com/image/fetch/$s_!33oj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 1272w, https://substackcdn.com/image/fetch/$s_!33oj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4de56b-5167-458d-a52e-9470e6e0113a_1632x550.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Courtesy: X</figcaption></figure></div><p>Both reactions make sense. That is the uncomfortable part.</p><p>The human cost of generating code has gone down significantly while the cost of trusting code has remained the same. Every team that adopts agents eventually runs into this conversion rate. Implementation time turns into verification debt. Sometimes the exchange rate is favorable. Sometimes it is awful.</p><p>That is the verification tax.</p><h2><strong>The Kelley-Karpathy Split Is Rational</strong></h2><p>I do not read Kelley&#8217;s position as nostalgia for hand-written code. I read it as a maintainer protecting the review loop. A compiler project is a hostile environment for median code. It cares about undefined behavior, portability, bootstrap constraints, diagnostics, performance, language design, and a hundred small invariants that are obvious only after years inside the project.</p><p>An agent can write code that looks like a contribution but the contributor remains a human, at least for now. That distinction matters. A human who submits a clumsy patch can learn the project. Review time may be an investment. A drive-by AI patch usually has no future learning curve attached to it. The human submitter can disappear, leaving the maintainer to explain the difference between &#8220;passes local tests&#8221; and &#8220;belongs in the compiler.&#8221;</p><p>So the ban is not irrational. It is a local policy for a system where review bandwidth is the production bottleneck.</p><p>Karpathy is also not irrational. He is reacting to a different production function. If I am building a prototype, exploring an API, or generating scaffolding around a clear boundary, an agent can be absurdly useful. I have had the same experience: the code appears faster than my hands can make it. The first draft often gets me to the real question sooner.</p><p>The split appears because people are measuring different loops. The enthusiast measures time-to-first-working-version. The skeptic measures time-to-correct-and-maintainable-version. Those are not the same metric. </p><blockquote><p>The perfection loop, even with agents in it, scales down the expected AI speedup.</p></blockquote><h2><strong>The METR Result Was A Warning, Not A Verdict</strong></h2><p>The best empirical work I have seen does not give either side a clean victory. METR&#8217;s 2025 randomized trial studied 16 experienced open-source developers working on 246 tasks in mature projects they already knew. The developers expected AI tools to make them faster. Afterward, they still felt faster. Measured task completion time went the other way: with the early-2025 tools in that setting, they were slower.</p><p>I would not turn that into a law. Sixteen developers is not civilization. The tools have already improved. The study also focused on mature projects, which are exactly where hidden context matters most.</p><p>But that is why I take the result seriously.</p><p>The interesting finding is not &#8220;AI makes developers slower.&#8221; The interesting finding is that experienced engineers can feel acceleration while the system slows down. Prompting feels like progress. Watching the agent stream code feels like progress. Accepting a patch feels like progress. The meter spins.</p><blockquote><p>Then the senior engineer starts paying the bill.</p></blockquote><p>They read the diff. They chase the invariant. They notice that the agent used the local helper but bypassed the authorization boundary. They ask why the migration touches a table it does not own. They wonder whether the &#8220;cleanup&#8221; changed behavior. None of this work vanished. It moved downstream.</p><p>A separate 2025 study of Copilot adoption in open-source projects found the same shape from another angle: less-experienced developers produced more, but the added maintenance and review burden shifted toward core developers. That is the profession in miniature. Output rises. Judgment becomes the choke point.</p><h2><strong>The Dangerous Code Looks Boring</strong></h2><p>A syntax error is a kindness, but we all know that the worst AI-generated code is not the code that obviously fails. </p><p>The <em>dangerous</em> patch looks cruelly normal. It follows the local naming style. It imports the expected library. It adds a test. The test is often too close to the implementation, but at a glance the ritual has been performed.</p><p>Then you look closer.</p><p>The schema migration assumes a nullable field is always present because every fixture had it. The retry loop catches the broad exception and converts a partial write into a silent success. The authentication check moved below a cache read because the agent optimized for the happy path. The refactor split one ugly function into four clean ones and lost the fact that a side effect had to happen before the second branch returned.</p><p>This is where senior engineers are feeling the profession change under their feet. The old loop was: think, type, run, revise. The new loop is closer to: specify, generate, inspect, constrain, reject, generate again. That is not a small tooling change. It changes where competence lives.</p><p>When I hand-write code, some checks happen before language. My hands do not type the broad catch. My hands do not put the auth check after the cache read. My hands have absorbed scars from old outages, old bugs, old reviews, old shame. The agent has absorbed public code. That is not nothing. It is also not my production history.</p><blockquote><p>So when the agent writes, the senior engineer has to externalize instincts that used to be silent. Write the invariant. Write the acceptance test. Write the boundary. Write the &#8220;do not touch this table&#8221; instruction. Write the review checklist. The tacit has to become executable.</p></blockquote><p>That is painful because tacit knowledge was part of the status game of engineering. The expert knew without saying. Agents punish that.</p><h2><strong>Legacy Humans Have The Same Problem As Legacy Systems</strong></h2><p>There is an obvious version of this argument for companies. A twenty-year-old enterprise system contains valuable domain knowledge in the worst possible format: tribal memory, stale diagrams, incident lore, Jira archaeology, Slack threads, and modules shaped by reorganizations no one remembers.</p><p>But the same thing is true of a twenty-year engineer.</p><p>The legacy engineer has immense knowledge. The question is whether that knowledge can be turned into constraints an agent can use. <strong>If it stays as private taste, the agent cannot benefit from it.</strong> If it becomes tests, interfaces, threat models, migration rules, and retrieval context, it becomes a force multiplier.</p><p>That is the pivot I care about.</p><p>The engineer who refuses all agents may still be right inside a compiler, kernel, database, allocator, or safety-critical system where the review tax overwhelms generation speed. The engineer who refuses to learn agent direction in ordinary product engineering is making a different bet: that typing will remain scarce enough to protect them.</p><p>I do not buy that bet.</p><p>Typing is getting less scarce. Good constraints are getting more scarce. So is taste. So is the ability to know which generated solution is subtly wrong.</p><h2><strong>The New Seniority</strong></h2><p>A junior developer with an agent can now create more surface area than a senior engineer can review. That sentence should make managers nervous.</p><p>It does not mean juniors become useless. It means the old apprenticeship model breaks if the junior never develops the internal model the agent is replacing. If all they learn is prompting and acceptance, they become fast at producing code they cannot defend.</p><p>It also does not mean senior engineers can retreat into purity. A senior who only says &#8220;no AI&#8221; may be protecting quality in one loop while losing the larger shift in production. The future engineer has to know how to create a harness around the agent: small diffs, deterministic tests, explicit contracts, locked migrations, typed APIs, repeatable benchmarks, permission boundaries, and review gates that fail before a human gets tired.</p><p>This is where my loyalties are. I am betting on top-down processing, but not the lazy version where a prompt replaces engineering. <strong>I mean top-down as constraint design.</strong> The human decides the shape of the system, the invariants that matter, the blast radius, the evaluation, and the language in which success is judged.</p><p>The agent fills in leaves. The human owns the tree.</p><p>That is a more abstract job, but it is not an easier one. It may require more engineering maturity, because the code no longer carries as many visible fingerprints of its author&#8217;s uncertainty. The uncertainty is still there. It is just hidden behind fluent syntax.</p><p>The verification tax is the price of that fluency.</p><p>I do not want to go back to a world where every leaf node is hand-written. I also do not want a world where nobody can explain why the generated forest is safe to walk through. </p><blockquote><p>The interesting work is in the middle: make human judgment explicit enough that machines can act inside it, and make machine output bounded enough that humans can still verify it.</p></blockquote><p>It is the <em>new software engineering</em> with the private parts of judgment dragged into the light.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog: Post-Human Engineering! 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 Tidy-First Economics of the Diff]]></title><description><![CDATA[Writing code is cheap. Proving a massive AI rewrite did not break production remains wildly expensive.]]></description><link>https://www.khola.blog/p/the-tidy-first-economics-of-the-diff</link><guid isPermaLink="false">https://www.khola.blog/p/the-tidy-first-economics-of-the-diff</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Thu, 18 Jun 2026 19:25:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!eZVU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The cost of drafting code has collapsed. An agent writes in seconds what used to take a sprint. But the cost of verifying that code has not moved at all. It is still a senior engineer reading a diff, line by line, deciding whether the system&#8217;s promises survived.</p><p>Kent Beck&#8217;s <em>Tidy First?</em> was written as a guide for human refactoring. Read in 2026, it is something stricter: a prerequisite for letting machines change production code without losing control of what the code actually does.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog: Post-Human Engineering! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eZVU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eZVU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!eZVU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!eZVU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!eZVU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eZVU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg" width="440" height="577.4278215223097" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:762,&quot;resizeWidth&quot;:440,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Tidy First?: A Personal Exercise in Empirical Software Design: Beck, Kent:  9781098151249: Amazon.com: Books&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Tidy First?: A Personal Exercise in Empirical Software Design: Beck, Kent:  9781098151249: Amazon.com: Books" title="Tidy First?: A Personal Exercise in Empirical Software Design: Beck, Kent:  9781098151249: Amazon.com: Books" srcset="https://substackcdn.com/image/fetch/$s_!eZVU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!eZVU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!eZVU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!eZVU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0854e4c5-45ea-4b25-a1de-ee4dfcdc0043_762x1000.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Fluency Trap</strong></h2><p>There is a natural signal of uncertainty in human code. Junior developers write syntax that looks hesitant. You can read a pull request and spot the boundaries of their understanding. The rough edges tell you where to focus.</p><p>Language models do not hesitate. They produce polished, confident syntax even when hallucinating logic. A function that silently drops an authentication check reads exactly like a function that preserves it. The visual signals of uncertainty are gone.</p><p>This is the fluency trap. Teams treat AI code review like human code review, approving massive diffs because they look professional. The actual technical debt being accumulated is trust without verification.</p><h2><strong>The Tangled Commit</strong></h2><p>A tangled commit mixes structural changes with behavioral changes. For a human author, this is annoying to review. For an agentic pipeline, it is the failure mode that matters most.</p><p>Consider a concrete scenario. An agent is asked to add request logging to a service. To &#8220;clean up&#8221; the file, it also extracts three helper functions, renames two variables, and flattens a nested conditional. The PR is 400 lines. The logging feature is 12 of them.</p><p>Buried in the extraction, the agent drops an early-return guard clause that validated an authentication token. The remaining 388 lines of syntactically perfect structural changes provide cover. The tests pass because no test targeted that specific guard. The reviewer, scanning for the logging feature, approves.</p><p>The privilege escalation ships silently. It surfaces weeks later, traced back to a &#8220;refactoring&#8221; nobody asked for.</p><p>When behavior and structure change in the same diff, verifying that no existing invariants were broken becomes intractable. The blast radius of the change exceeds what any reviewer can hold in working memory. Reliability decays with the size of an unverified rewrite, and the decay is steep.</p><h2><strong>The Cost Asymmetry</strong></h2><p>Beck roots <em>Tidy First?</em> in two economic principles: the time value of money and the option value of code. Software creates value in two ways. What it does today, and what it could do tomorrow. A well-structured module preserves the option to change cheaply later. A tangled module forecloses that option by coupling every future change to a full rewrite.</p><p>When agents write the code, the generation half of this equation collapses. The cost of producing a first draft approaches zero. But the verification half stays fixed. A senior engineer still has to read the diff, trace the invariants, and decide whether the system&#8217;s contracts survived. That labor does not scale with the speed of generation.</p><p>The result is a permanent asymmetry. There are tasks where AI delivers clear returns: converting a messy JSON payload into a strictly typed DTO against a deterministic schema, or writing a pure function that an existing test harness can validate instantly. Generation is expensive to do by hand, and verification is cheap. The economics work.</p><p>Then there are tasks where the savings are illusory. A cross-repository refactoring, a complex business logic change, a structural migration. The agent generates the code in seconds, but the reviewer must re-derive the agent&#8217;s reasoning path across the entire dependency graph. The cognitive labor does not disappear. It relocates downstream, lands on the reviewer, and gets more expensive because the diff is bigger and the intent is less legible than a human&#8217;s.</p><p>Organizations that measure productivity by commit throughput are measuring the wrong side of the equation. The constraint is verification. The metric that matters is how quickly a reviewer can confirm that a diff did what it claims and nothing else. Every tangled commit makes that confirmation slower. Every isolated tidy makes it faster.</p><h2><strong>Guard Clauses and Dead Code: Why Tidying Is Physical</strong></h2><p>Beck&#8217;s tidying maneuvers read differently when the coder is a transformer.</p><p>Guard clauses. Beck recommends returning early to reduce cognitive load. For an agent, a guard clause physically flattens the abstract syntax tree. Flat ASTs mean the model spends less attention capacity tracking nested conditional state. Each level of nesting is a branch the transformer must hold in its weights during generation. Flatten the branches and you reduce the probability of a logic inversion. The tidying changes the computation.</p><p>Dead code removal. Beck says delete dead code because it confuses humans. The agentic version is harsher: dead code poisons the prompt. An agent reading a deprecated branch will sample tokens from it and generate hallucinations based on obsolete interfaces. Every unreachable function is a tax on the context window. You pay for that mess in tokens, latency, and degraded reasoning. Dead code removal is garbage collection for the prompt.</p><p>These are not metaphors. Guard clauses reduce the model&#8217;s branch prediction state-space. Dead code removal shrinks the noise floor of the context window. Beck&#8217;s tidying maneuvers have mechanical consequences for transformer-based generation that he could not have anticipated.</p><h2><strong>Ousterhout&#8217;s End-State and Beck&#8217;s Transition Function</strong></h2><p>I wrote previously about <a href="https://www.khola.blog/p/ousterhout-was-right-but-the-game">John Ousterhout&#8217;s &#8220;Deep Modules.&#8221;</a> Deep modules define the spatial shape a codebase needs for constrained LLM attention to work. They give the agent a clean boundary to operate within.</p><p>But how do you reach that state safely when the current codebase is a shallow, coupled mess?</p><p>Beck&#8217;s answer is the transition function. You tidy first, verify that behavior did not change, then alter behavior in a separate step. The tidying moves the structure toward Ousterhout&#8217;s ideal. The separation ensures you can prove each step independently.</p><p>Skip the separation and watch what happens. An agent is asked to add a caching layer to a service with a shallow, highly coupled module structure. To make the cache fit, the agent refactors the data access layer: extracting interfaces, renaming internal methods, consolidating three query functions into one. The cache works. But the consolidated query function silently changed the sort order of results because the agent optimized for the cache&#8217;s access pattern rather than preserving the original contract. The tests pass because no test asserted sort order. The regression surfaces in a downstream report that nobody connects to the caching PR for weeks.</p><p>The agent did two things in one step. You can verify neither independently. Beck&#8217;s rule prevents this by making the structural tidy a separate, provable operation. The feature prompt inherits a clean structure and produces a small, focused diff.</p><p>You cannot ask an agent to refactor a shallow module into a deep module while simultaneously adding a new feature. Current models routinely fail on multi-file structural refactoring, frequently dropping branches or inverting logic. The transition must be isolated. Tidy, then verify. Only then, change behavior.</p><h2><strong>The Two-Prompt Pipeline</strong></h2><p>Agents are fast and compute is cheap. Why bother tidying? Just let the agent rewrite the whole file.</p><p>Because a 400-line whole-file rewrite by a non-deterministic model is a reliability problem you cannot review your way out of. Writing is cheap. Proving the rewrite did not introduce a silent failure remains wildly expensive.</p><p>The defense is a strict two-prompt pipeline that isolates structural refactoring from feature generation.</p><p><strong>Phase one: the pure refactor.</strong> The agent is prompted strictly to tidy the structure without altering behavior. This phase is constrained by a tripwire test: a locked unit test written before the agent touches the file, targeting the exact data contract of the module. The agent is forbidden from editing the tripwire. If the structural tidy accidentally alters runtime behavior, the tripwire fails and the loop terminates.</p><p>A tripwire test for a user service might look like this:</p><pre><code><code>// LOCKED &#8212; do not modify. Tripwire for structural tidy.
test('user service contract', () =&gt; {
  const result = createUser({ name: 'test', role: 'viewer' });
  expect(result).toStrictEqual({
    id: expect.any(String),
    name: 'test',
    role: 'viewer',
    permissions: ['read'],
  });
});
</code></code></pre><p>If the agent&#8217;s refactoring changes the return shape, the permissions array, or the role mapping, this test catches it before the PR exists.</p><p><strong>Phase two: the behavioral delta.</strong> Only after the structural changes have been committed and verified does the agent receive the second prompt: add the feature. Because the codebase was tidied in phase one, the feature diff is small and isolated. The reviewer reads a focused block of business logic instead of parsing 400 lines of mixed intent.</p><p>By separating the prompts, the pipeline creates a verification boundary. Each diff answers one question. Did the structure change safely? Did the behavior change correctly? The reviewer never has to answer both at once.</p><h2><strong>The Diff as the Unit of Trust</strong></h2><p>The future of software economics belongs to the teams that enforce the strictest structural boundaries around their agents.</p><p>I do not review code anymore. I review diffs. The diff is the unit of trust in a codebase maintained by machines. When that diff is clean and isolated, I can verify it. When it tangles structure and behavior into a single commit, I cannot. No one can. The reviewer&#8217;s correction ability drops toward zero, and whatever the agent introduced ships unchecked.</p><p>The engineering role has shifted. I write the interface. I write the tripwire test. I set the boundary that triggers an alarm when the agent crosses it. The agent implements. I own what ships.</p><p>Writing is cheap. The proof is expensive. The only way to afford the proof is to keep the diff small enough to read.</p><p>Tidy first. The machine cannot guess what you meant.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog: Post-Human Engineering! 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[Ousterhout Was Right. But the Game Has Changed.]]></title><description><![CDATA[Deep modules were a cognitive convenience for human engineers. For autonomous agents, they are a hard architectural requirement.]]></description><link>https://www.khola.blog/p/ousterhout-was-right-but-the-game</link><guid isPermaLink="false">https://www.khola.blog/p/ousterhout-was-right-but-the-game</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Thu, 11 Jun 2026 17:04:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_by6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I keep a copy of <em>A Philosophy of Software Design</em> on a short shelf. Eight books, maybe. The ones I still argue with.</p><p>Ousterhout&#8217;s argument is simple: the enemy of a good codebase is complexity, and the weapon against it is the deep module, a simple interface masking a large hidden implementation. His justification was cognitive load. Human brains hold limited state. Deep modules reduce what you need to hold simultaneously. That justification is now beside the point. The conclusion is more important than ever.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog: Post-Human Engineering! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_by6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_by6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_by6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_by6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_by6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_by6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg" width="326" height="401.2307692307692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:975,&quot;resizeWidth&quot;:326,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A Philosophy of Software Design&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Philosophy of Software Design" title="A Philosophy of Software Design" srcset="https://substackcdn.com/image/fetch/$s_!_by6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_by6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_by6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_by6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71ffccd1-52ba-4136-9736-7d40afcc9499_975x1200.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The thing doing most of the implementation work in a modern codebase is running on a transformer with a bounded attention mechanism and a hard token budget. Its cognitive limit is a hardware constraint. When you hand it a shallow module, the failure is a broken production invariant that surfaces three months later with no traceable origin.</p><h2><strong>The Private State It Was Not Supposed to Touch</strong></h2><p>Here is the failure mode that clarified this for me. A research team tasked an LLM-based coding agent with adding a statistics dashboard to an existing React application. The app had a public API for reading task data. The agent inspected the interface, found several preconditions to satisfy and parameters to order correctly, and made a calculation.</p><p>It skipped the API. It reached into the internal state store and wrote directly to <code>_todos</code> and <code>_nextId</code>, two private variables that were never part of the contract.</p><p>Every test passed. The feature shipped. Six months later, a developer refactored the internal state representation. The statistics dashboard broke silently, returning stale numbers with no exception raised, no error logged at the call site, nothing. Just wrong output that a user eventually noticed.</p><blockquote><p>The agent took the cheaper path, not the correct one. The shallow public API cost more tokens to satisfy than writing to the private array. So it wrote to the private array. That is the optimization function at work: minimize tokens, pass the tests, ship the diff.</p></blockquote><p>Ousterhout spent a chapter explaining why information hiding matters. The agent confirmed it empirically, by violating it.</p><h2><strong>What the Benchmarks Say About Boundaries</strong></h2><p>The behavioral data at scale matches the pattern from that single incident.</p><p>Autonomous agents on SWE-bench, which draws from real GitHub issues across production repositories, resolve roughly 71% of tasks requiring a single-file edit. On tasks requiring changes across multiple files, that drops to roughly 28%. Forty-three points. The gap is not a task difficulty artifact. It is what happens when an agent needs to trace across an abstraction boundary to understand what a change will do.</p><p>A deep module makes that boundary cheap. Load the signature, understand the contract, work. A shallow module makes the boundary expensive. Load the implementation, load the callers, load whatever adjacent module holds the state this function implicitly depends on, load the configuration that gates behavior. Every file is tokens. Every token is attention budget that the model cannot spend on reasoning.</p><blockquote><p>You cannot solve this by expanding the context window. A million tokens of shallow module dependency graph does not give the model more understanding. It dilutes the signal with more surface area. The agent still fails; it just fails more expensively.</p></blockquote><h2><strong>What Gets Generated When You Ask for Modular Code</strong></h2><p>Tell an agent to write modular code. Watch what comes out.</p><p>Files will be small. Directories will be organized. Interfaces will be defined and injected. It will look correct on a whiteboard. Then try to change a single struct and discover that the definition has leaked into six different files, each of which needs to be updated atomically or the system breaks. The agent distributed a single logical responsibility across the filesystem rather than encapsulating it. The coupling is real; the modularity is cosmetic.</p><p>Researchers who systematically analyzed AI-generated codebases at scale named this the &#8220;Modular Mirage.&#8221; The visual pattern of modularity is present. The semantic isolation that makes modularity useful is absent.</p><p>The longitudinal benchmark SWE-CI measures what happens to a codebase over months of agentic maintenance, spanning commits rather than single pull requests. Across those continuous integration loops, most autonomous agents introduced breaking regressions into previously working code on more than 75% of extended tasks. The agent fixed the current ticket. It walked backward over something that worked. The reason is shallow boundaries: a local edit had non-local consequences the agent could not see from within its context window.</p><h2><strong>The &#8220;Define Errors Out of Existence&#8221; Chapter Lands Differently Now</strong></h2><p>Ousterhout&#8217;s advice here is to design APIs so that certain errors cannot occur at the call site. If a <code>substring</code> function returns empty on out-of-bounds indices rather than throwing, the caller never needs to handle an exception that carries no actionable information.</p><p>Read that chapter again with an agent in the caller role.</p><p>An agent hitting an API that throws granular exceptions must write branching logic. It must predict the shape of the error object. It must anticipate edge cases that the API designer could have swallowed once and hidden from everyone downstream. LLMs do this poorly. They will guess the error structure, write a try-catch that catches too broadly, and move on. When the function returns a success code on a corrupted internal state, the agent proceeds to build the next layer on that foundation. The error surfaces far from the origin, in behavior that looks plausible for a while before it obviously is not.</p><p>There is a term for this failure mode in the research: silent failure rate, meaning the proportion of API contract violations that produce wrong behavior without raising an exception. Silent failures compound across agentic workflows in a way they never did with human developers, because the human would notice the wrong output during review. The agent will not.</p><p>State-of-the-art coding agents top out around 34% success when patching confirmed security vulnerabilities. A large fraction of that failure traces back to this: the agent patches the visible exception path and misses the invariant that was being enforced implicitly by the calling code it just restructured.</p><p>An interface that cannot be called incorrectly is not merely a convenience, for agents, it is the only safe interface to expose.</p><h2><strong>The Margin Note I Would Add to Chapter 11</strong></h2><p>Ousterhout&#8217;s &#8220;design it twice&#8221; principle is about forcing yourself to draft a second interface before committing to the first. The discipline surfaces what the first draft was actually exposing.</p><p>My margin note: every parameter in the signature is a token you are billing your agent maintainer.</p><p>The practical test I run before approving any interface: can an LLM use this correctly, zero-shot, from the function signature and a one-line docstring, with no additional context loaded? If the answer is no, the interface is too shallow. That standard is Ousterhout&#8217;s standard. The entity being measured has changed, and the measurement has gotten stricter.</p><p>Expose twelve configuration flags and you have written a form, not a module. A probabilistic system will fill it out incorrectly.</p><h2><strong>What the Book Got Right About a Problem It Did Not Know Existed</strong></h2><p><em>A Philosophy of Software Design</em> was written for an era when the bottleneck was human working memory. The advice was correct. The frame was narrow.</p><p>Deep modules are the only mechanism that gives an autonomous agent a cleanly bounded scope to work in. The interface becomes the contract that defines what the agent can safely assume, touch, and ignore. When that contract is weak, the agent does not operate on a module. It operates on the entire graph of things the module implicitly depends on, which may be larger than its context window and will certainly be larger than what its attention mechanism can hold coherently.</p><blockquote><p>The senior engineer&#8217;s job in 2026 is not writing code. I write the interface. I write the test. I set the boundary that triggers an alarm when the agent crosses it. The agent implements. I own what ships.</p></blockquote><p>Ousterhout did not intend to write the survival manual for the post-human codebase. Reading it in 2026, that is what it is.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog: Post-Human Engineering! 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[CLRS Is the Review Manual for Machine-Written Code]]></title><description><![CDATA[When agents write the code, the classic algorithms textbook becomes a review manual.]]></description><link>https://www.khola.blog/p/clrs-is-the-review-manual-for-machine</link><guid isPermaLink="false">https://www.khola.blog/p/clrs-is-the-review-manual-for-machine</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Thu, 04 Jun 2026 03:35:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DjFV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I do not want to write another memory-wall post. Khola.Blog has already asked modern CPUs to testify under oath, and they have been very clear: scattered memory is expensive.</p><p>The more interesting reread of <em>Introduction to Algorithms</em> in 2026 is not that the RAM model hides cache behavior. It does. That is old news here.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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>The interesting part is that CLRS becomes more important when code is cheap.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DjFV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DjFV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DjFV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DjFV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DjFV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DjFV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg" width="272" height="309.79498861047836" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:878,&quot;resizeWidth&quot;:272,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Introduction to Algorithms, fourth edition: 9780262046305: Computer Science  Books @ Amazon.com&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Introduction to Algorithms, fourth edition: 9780262046305: Computer Science  Books @ Amazon.com" title="Introduction to Algorithms, fourth edition: 9780262046305: Computer Science  Books @ Amazon.com" srcset="https://substackcdn.com/image/fetch/$s_!DjFV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DjFV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DjFV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DjFV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F421b4d0d-6d8f-4363-ba61-48aa360080d7_878x1000.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When an agent writes an algorithm, the first question is no longer &#8220;can someone type the implementation?&#8221; The first question is &#8220;what did this implementation promise, and can I prove it kept the promise?&#8221;</p><p>That is the part of CLRS that survives. Not the fantasy that every memory access costs the same. Not the idea that a textbook data structure is automatically a production data structure. The durable part is the discipline: invariants, bounds, recurrences, amortized reasoning, reductions, and worst-case analysis.</p><p>I do not read CLRS as a performance manual. I read it as the language a reviewer needs when the patch was written by something fast, confident, and indifferent to production.</p><h2><strong>The Book Is About Promises</strong></h2><p>The most useful thing CLRS teaches is not a catalog of named algorithms. It is a way to talk about promises.</p><p>A loop invariant says what must remain true before and after each iteration. A worst-case bound says what happens when the input stops being friendly. Amortized analysis says when a rare expensive operation is paid for by a sequence. A reduction says one problem is at least as hard as another. Work and span say parallelism has a critical path, no matter how many processors the scheduler can see.</p><p>Those ideas are not academic decoration. They are review tools.</p><p>If a generated function claims to maintain a sorted prefix, I want the invariant. If it claims expected linear time, I want to know where the randomness comes from and who can influence the input. If it claims amortized constant time, I want to know whether the tail event is acceptable in the caller&#8217;s fault domain. If it spawns work aggressively, I want to know where the span ends and where coordination overhead starts.</p><p>Sample tests do not answer those questions. They show that the code survived a small cross-examination.</p><p>CLRS gives a reviewer the better cross-examination.</p><h2><strong>The RAM Model Stops At The Hot Path</strong></h2><p>The RAM model is a deliberate simplification. It gives every ordinary memory access a constant cost so the proof can focus on how the algorithm scales.</p><p>That is not a bug in CLRS. That is the contract of the model.</p><p>The mistake is carrying that model into a hot path after the proof is done. Two traversals can both be <code>O(n)</code> and still behave nothing alike. A scan over a contiguous vector gives the processor a boring access pattern. A walk through a linked structure creates a chain of dependent addresses. The notation groups them together because asymptotic analysis is answering a different question.</p><p>This is why I do not want the CLRS post to become another cache sermon. The hardware lesson matters, but it is not the main event. The practical rule is smaller:</p><blockquote><p><em>Use CLRS to prove the shape of the algorithm. Use the machine to price the implementation.</em></p></blockquote><p>Big-O gets the first vote. The profile gets the final one.</p><h2><strong>Production Libraries Are Edited Algorithms</strong></h2><p>The best production algorithms are rarely naked textbook algorithms. They are edited algorithms.</p><p><a href="https://blog.rust-lang.org/2024/09/05/Rust-1.81.0/">Rust 1.81</a> began replacing its stable and unstable slice sorting implementations, but it took until Rust 1.95 in April 2026 to finally roll the new logic out across every single <code>sort_by</code>, <code>sort_by_key</code>, and <code>select_nth</code> variant in the standard library. The new algorithms improve runtime performance and compilation time, and also actively try to detect incorrect <code>Ord</code> implementations that would prevent a meaningful sorted result.</p><p>That second point is the one I care about for this post.</p><p>Sorting is not just &#8220;put these values in order.&#8221; Sorting assumes the comparison relation behaves like an order. If the comparator violates that contract, the algorithm is no longer operating on the problem it was designed to solve. Rust&#8217;s current <a href="https://doc.rust-lang.org/std/primitive.slice.html">slice documentation</a> describes the stable sort as based on driftsort, combining quicksort&#8217;s fast average case with mergesort&#8217;s worst-case behavior and run detection. It also warns that invalid ordering can panic or produce unspecified order. Making that safe and fast across every variant required deep, layout-aware engineering. The textbook algorithm is just the starting point; the production implementation is an exercise in managing the machine.</p><p>That is CLRS in production clothing: the algorithm needs a mathematical contract before performance even enters the room.</p><p>Hash tables make the same point from the data-structure side. Abseil&#8217;s <a href="https://abseil.io/about/design/swisstables">Swiss Table design notes</a> describe metadata bytes and group matching for lookup. Its <a href="https://abseil.io/docs/cpp/guides/container">container guide</a> recommends <code>absl::flat_hash_map</code> and <code>absl::flat_hash_set</code> for general use, while spelling out the trade-off: flat storage helps the general case, but rehashing invalidates pointers and node-based variants still matter when pointer stability is required.</p><p>That is the engineering version of the CLRS lesson. The asymptotic target is not enough. The implementation has to choose which promise matters: lookup speed, pointer stability, memory overhead, iteration behavior, adversarial input resistance, or migration safety.</p><p>The textbook gives the vocabulary. The library makes the trade.</p><h2><strong>The New Failure Mode Is Plausible Wrong Code</strong></h2><p>The dangerous agent output is not always nonsense. Nonsense is easy.</p><p>The dangerous output compiles. It has the right shape. It imports the local helper. It passes the examples in the prompt. It looks boring enough to merge.</p><p>Then the comparator is not a total order. The recursive dynamic program has no real memoization boundary. The randomized algorithm uses a predictable source. The priority queue choice is fine for the lecture but wrong for the update pattern. The graph traversal mutates the structure whose invariant it is pretending to inspect.</p><p>These are not aesthetic failures. They are contract failures.</p><p>A human reviewer can miss them too. The agentic shift just changes the volume and confidence of the patches. It moves the hard work from writing code to rejecting code that is plausible but underspecified.</p><p>That is why the review should not begin with style. Style can wait. First, I want the algorithmic contract:</p><ol><li><p>What invariant does this code preserve?</p></li><li><p>What is the worst case, and who can trigger it?</p></li><li><p>Is the expected-case argument relying on randomness, distribution, or trust?</p></li><li><p>Does the amortized event fit the caller&#8217;s latency budget?</p></li><li><p>Which input breaks the mental model but still satisfies the type signature?</p></li><li><p>Is this a place to use a standard library implementation instead of generated code?</p></li><li><p>If the path becomes hot, what data layout does the proof ignore?</p></li></ol><p>That checklist is not anti-agent. It is anti-magic.</p><h2><strong>The Margin Note</strong></h2><p>I would not write &#8220;the RAM model is a lie&#8221; in my copy of CLRS. That is too cute and not quite true.</p><p>I would write this instead:</p><blockquote><p><em>Valid for proof. Insufficient for cost. Mandatory for review.</em></p></blockquote><p>The first sentence protects the book. The second protects the system. The third is the update for machine-written code.</p><p>CLRS does not teach agents to write good software. It gives humans the language to reject software that only looks good. That distinction matters more now, not less, because the cost of producing plausible code has collapsed.</p><p>The workflow does not just need faster generation. It needs stricter judgment. Every generated algorithm still owes the same debt: state the invariant, respect the bound, name the bad input, and prove that the implementation you shipped is the one the proof was talking about.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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 Pragmatic Programmer After the Memory Wall]]></title><description><![CDATA[What still holds when agents write code quickly, hardware punishes indirection, and cloud control planes fail at global scale.]]></description><link>https://www.khola.blog/p/the-pragmatic-programmer-after-the</link><guid isPermaLink="false">https://www.khola.blog/p/the-pragmatic-programmer-after-the</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Thu, 28 May 2026 03:26:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!D1u5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D1u5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D1u5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!D1u5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!D1u5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!D1u5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D1u5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg" width="309" height="404.0769230769231" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1904,&quot;width&quot;:1456,&quot;resizeWidth&quot;:309,&quot;bytes&quot;:2802494,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.khola.blog/i/199548774?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D1u5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!D1u5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!D1u5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!D1u5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2343b98b-9905-411a-ba9a-065df94730bc_2080x2720.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I do not think <em>The Pragmatic Programmer</em> has aged out. I think the environment around it has become less forgiving.</p><p>The book is not really about tools. It is about engineering posture: take responsibility, keep systems easier to change, make feedback loops tight, test what can fail, and refuse to live with broken windows. That posture still holds. What changed is the failure surface.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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>In 2026, a code agent can produce a week of mediocre abstraction before lunch. A laptop-class chip can execute billions of instructions per second and still spend the hot path waiting on scattered memory. A global control plane can replicate bad state across regions faster than a human can open the incident channel.</p><p>That does not make pragmatism obsolete. It makes the old advice more literal.</p><h2><strong>ETC Has a Physical Layer</strong></h2><p>The book&#8217;s central design rule is ETC: easier to change. That rule is still the right one. The mistake is treating &#8220;easier to change&#8221; as a synonym for &#8220;more abstract.&#8221;</p><p>That is how codebases end up with a hierarchy for every noun, an interface for every class, and a dependency-injected trail of breadcrumbs between one integer and the next. It feels civilized in review. It often benchmarks like a pile of receipts.</p><p>Modern CPUs do not run class diagrams. They fetch cache lines.</p><p><a href="https://download.intel.com/newsroom/2024/client-computing/Lunar-Lake-Architecture-Fact-Sheet.pdf">Intel&#8217;s Lunar Lake design</a> puts more attention on power, memory proximity, and a memory-side cache. <a href="https://www.apple.com/newsroom/2025/10/apple-unleashes-m5-the-next-big-leap-in-ai-performance-for-apple-silicon/">Apple&#8217;s M5</a> pushes unified memory bandwidth to 153 GB/s. Those are not licenses to ignore locality. They are evidence that silicon vendors are spending real die area and packaging complexity to hide the cost of moving data.</p><p>Software can still defeat all of it with pointer chasing.</p><p>The common agent failure is not exotic. Ask for a particle update loop, a pricing pass, a simulation tick, or a ranking transform, and the default output often looks like this:</p><pre><code><code>struct Particle {
    float x;
    float y;
    float z;
    float vx;
    float vy;
    float vz;

    void step(float dt) {
        x += vx * dt;
        y += vy * dt;
        z += vz * dt;
    }
};

std::vector&lt;Particle&gt; particles;</code></code></pre><p>That shape is fine until the loop matters. Then every iteration drags fields through memory as an object bundle, whether the CPU needs all of them or not.</p><p>For a hot loop, I want the data shaped around the access pattern:</p><pre><code><code>struct ParticleBlock {
    std::vector&lt;float&gt; x;
    std::vector&lt;float&gt; y;
    std::vector&lt;float&gt; z;
    std::vector&lt;float&gt; vx;
    std::vector&lt;float&gt; vy;
    std::vector&lt;float&gt; vz;

    void step(float dt) {
        for (size_t i = 0; i &lt; x.size(); ++i) {
            x[i] += vx[i] * dt;
            y[i] += vy[i] * dt;
            z[i] += vz[i] * dt;
        }
    }
};
</code></code></pre><p>This is not an argument for flattening the whole application into arrays. It is an argument for performance tiers.</p><p>Business policy can afford indirection. Hot loops, storage engines, serialization paths, rendering, compression, matching, ranking, and simulation usually cannot. In those places, ETC means the future maintainer can find the data flow, predict the memory access, and benchmark the change without spelunking through ceremony.</p><p>The pragmatic move is not &#8220;object-oriented&#8221; or &#8220;data-oriented.&#8221; The pragmatic move is knowing which part of the system is paying rent to the cache hierarchy.</p><h2><strong>Big-O Is Missing the Invoice</strong></h2><p>Big-O is not wrong. It is incomplete.</p><p>It throws away constants because that is what makes asymptotic reasoning useful. The machine puts those constants back with interest. A branch mispredict, a cold cache line, a TLB miss, a failed prefetch, and a recursive call frame all live outside the clean little expression.</p><p>That is why production sorting implementations use hybrids. The high-level algorithm carries the asymptotic guarantee. The small-partition fallback respects the machine.</p><p>For tiny contiguous ranges, insertion sort can beat a theoretically superior algorithm because it walks memory in a boring pattern. Boring is a feature. The hardware can prefetch it. The branch predictor can learn it. The compiler can see it.</p><p>The lesson is not &#8220;always use insertion sort.&#8221; That would be a cargo cult with a better haircut. The lesson is that the crossover point belongs to the benchmark, not the blog post.</p><p>This is the update I would write into the margin of the book: estimate first, then measure at the physical boundary. If the path is CPU-bound, measure cache misses. If it is I/O-bound, measure queueing and tail latency. If it is distributed, measure retries, coordination, and blast radius.</p><p>An asymptotic proof is the start of the conversation. A profile is where the machine gets a vote.</p><h2><strong>Agents Make Broken Windows Cheap</strong></h2><p>The book&#8217;s broken-window rule gets more important when code is cheap.</p><p>A human usually leaves a broken window one commit at a time: a vague name, a duplicated branch, a swallowed exception, a test skipped because the release is late. An agent can stamp out the same damage across twenty files with a confidence that feels suspiciously like authority.</p><p>The dangerous part is not that agent-generated code is bad. The dangerous part is that it is plausible.</p><p>It compiles. It uses the local framework. It names things in the house style. It may even come with tests. Then the system gets a new retry loop without jitter, a cache without invalidation, a transaction boundary around network I/O, or a catch-all handler that turns a real fault into quiet data corruption.</p><p>That changes the human job.</p><p>I do not review agent output as prose. I review it as an untrusted patch from a fast junior engineer with perfect typing and no memory of production.</p><p>The review checklist is blunt:</p><ol><li><p>What invariant does this code claim to preserve?</p></li><li><p>Where does it fail closed, fail open, or fail loud?</p></li><li><p>What resource does it acquire, and where is that resource released?</p></li><li><p>What happens under retry, cancellation, partial failure, and duplicate delivery?</p></li><li><p>Which test would have failed before the fix?</p></li><li><p>Which benchmark proves the abstraction did not move the bottleneck?</p></li></ol><p>That is not anti-agent. It is pro-accountability.</p><p>I would also keep an agent audit trail for serious systems. Not a theatrical &#8220;AI disclosure&#8221; badge. Useful metadata: model family, tool permissions, prompt or task summary, human approver, files touched, tests run, and any ignored failures.</p><p>The point is not blame. The point is defect analysis. If one model or workflow repeatedly creates the same kind of race, leak, or injection bug, I want that pattern visible.</p><p>Pride of ownership still means what it meant in the book. I signed the change. I own the blast radius.</p><h2><strong>Paranoia Survived Contact With Reality</strong></h2><p>The strongest part of <em>The Pragmatic Programmer</em> is its distrust of happy paths.</p><p>That distrust looked almost old-fashioned during the era of framework optimism. It does not look old-fashioned after the 2025 cloud incidents.</p><p><a href="https://aws.amazon.com/message/101925/">AWS published a summary</a> of the October 19-20, 2025 DynamoDB disruption in us-east-1. The root trigger was a latent race condition in DynamoDB&#8217;s automated DNS management system. A stale DNS plan was applied, cleanup removed the active regional endpoint addresses, and DynamoDB endpoint resolution failed. The primary DynamoDB disruption recovered in hours, but EC2 instance launch recovery took far longer because dependent control-plane systems had entered congestive collapse.</p><p>That is the part worth studying. The first bug was a race. The real lesson was coupling.</p><p>A regional DNS management defect impaired a foundational datastore. Services that depended on that datastore could not make forward progress. Recovery created a herd effect. The system then needed throttling, restarts, and careful queue reduction before it could breathe again.</p><p><a href="https://status.cloud.google.com/incidents/ow5i3PPK96RduMcb1SsW">Google Cloud&#8217;s June 12, 2025 incident</a> was smaller in duration but cleaner as a lesson. Google described a Service Control change for quota policy checks that lacked the right error handling and was not protected by a feature flag. A policy update inserted blank fields into regional Spanner tables. The metadata replicated globally within seconds. The null pointer path crashed Service Control binaries across regions and some restarting tasks created a herd effect on the underlying Spanner table.</p><p>The bug was not mysterious. The propagation path was.</p><p>This is pragmatic paranoia in production language:</p><ol><li><p>State that can replicate globally needs staged propagation.</p></li><li><p>Automated deletion needs velocity limits.</p></li><li><p>Critical policy paths need feature flags that default off.</p></li><li><p>Control planes need failure isolation from the services they manage.</p></li><li><p>Restart loops need jitter and backoff before they become load generators.</p></li><li><p>Monitoring cannot depend entirely on the system it is meant to diagnose.</p></li></ol><p>&#8220;Crash early&#8221; is still good advice inside a bounded fault domain. It is reckless advice when the crash loop can synchronize globally.</p><p>The rule I use is simple: crash local, recover global. Assert at the boundary where bad state enters. Quarantine the bad input. Keep the serving path degraded if safety allows it. Make the supervisor boring, bounded, and explicit.</p><h2><strong>The Merge Queue Is Now Architecture</strong></h2><p>The book treats automation as a professional baseline. That part now includes the merge queue.</p><p>When agents produce many small patches, a sequential queue becomes a throughput bottleneck and a correctness risk. A long queue encourages bigger batches. Bigger batches make failures harder to isolate. Harder isolation creates slower review. Slower review invites more automation to pile up behind it.</p><p>That is a feedback loop, not a tooling inconvenience.</p><p>Speculative CI is the right mental model. Test the next few queued changes against predicted future states of <code>main</code>. If patch A is expected to land, test B on top of A. If A fails, throw away the speculation and recompute. The trade is obvious: spend more compute to protect human attention and reduce queue latency.</p><p>The expensive part is deciding what to test.</p><p>I want deterministic test selection based on ownership and dependency graphs. I want property tests around parsers, protocol boundaries, money movement, authorization, and data structure invariants. I want replay of historical counterexamples before random generation burns a cluster. I want performance checks only where the patch touches a known hot path.</p><p>The starter kit is no longer just formatter, unit tests, and CI. For agent-heavy development, the starter kit is the operating system for trust.</p><h2><strong>What I Would Change In My Copy</strong></h2><p>I would not rewrite <em>The Pragmatic Programmer</em>. I would add margin notes.</p><p>Next to ETC, I would write: &#8220;Easier to change includes easier to profile.&#8221;</p><p>Next to DRY, I would write: &#8220;Agents duplicate intent more often than text.&#8221;</p><p>Next to Design by Contract, I would write: &#8220;Contracts are the spec the agent does not get to improvise.&#8221;</p><p>Next to Crash Early, I would write: &#8220;Only inside a fault domain with a supervisor.&#8221;</p><p>Next to Don&#8217;t Live With Broken Windows, I would write: &#8220;Machine-generated broken windows still count.&#8221;</p><p>Next to Pragmatic Teams, I would write: &#8220;The human team owns context. The agent owns nothing.&#8221;</p><p>That last one is the real update.</p><p>The industry keeps trying to turn software engineering into text generation. The book&#8217;s answer is still better: software engineering is judgment under constraint. Tools change the cost curve. They do not remove responsibility.</p><p>I want agents in the workflow. I also want cache-aware data structures, explicit invariants, boring release controls, and incident reports that name the coupling. The distinguished engineer in 2026 is not the person who types the most code. It is the person who can still see the system after the code becomes cheap.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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[SICP: An Architectural Trace of Pointer Chasing and Environment Retention on Modern Silicon]]></title><description><![CDATA[Why the elegant abstractions of classical computer science fail under the thermal and spatial constraints of 2026 microarchitectures.]]></description><link>https://www.khola.blog/p/sicp-an-architectural-trace-of-pointer</link><guid isPermaLink="false">https://www.khola.blog/p/sicp-an-architectural-trace-of-pointer</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Thu, 21 May 2026 02:42:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UQoO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UQoO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UQoO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UQoO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UQoO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UQoO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UQoO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg" width="406" height="584" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:584,&quot;width&quot;:406,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:57483,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.khola.blog/i/198645179?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe41e3f69-c5e7-45cb-803d-9d0dffcba467_612x792.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UQoO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UQoO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UQoO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UQoO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc73ba2f5-1d89-431c-92e5-f2385bf44900_406x584.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Structure and Interpretation of Computer Programs teaches that computer science is a branch of mathematical logic. It builds processes in an idealized sandbox where memory is infinite, pointer dereferences are instantaneous, and execution frames carry zero cost.</p><p>Nevertheless, in the systems of 2026, hardware is not a mathematical plane. It is a thermal and spatial grid. The elegant abstractions of classical computer science run directly into microarchitectural bottlenecks. Specifically, lexical environments and closures collapse under the physical constraints of the memory wall.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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>Structurally, we must discard the illusion of infinite memory to analyze how software structures interact with the silicon layer.</p><h2><strong>The Microarchitectural Cost of Pointer Chasing</strong></h2><p>Modern out-of-order execution engines derive their massive throughput from memory-level parallelism. Linear array scanning aligns perfectly with hardware prefetchers, allowing the CPU to compute the address of the next contiguous element instantly. Speculative loads pull cache lines into the L1 cache before the execution engine requests them. Consequently, the effective latency approaches the blazing fast 3-cycle L1 speed of the Apple M4.</p><p>Conversely, sequential pointer chasing is inherently hostile to modern hardware pipelines. Lisp pairs, binary trees, and deeply nested closures rely on scattered heap allocations. When traversing a linked list, the exact memory address of the subsequent node remains unknown until the current node&#8217;s payload is fetched from main memory.</p><p>This serialization creates an unbreakable dependency chain that blinds the hardware prefetcher. As memory-level parallelism collapses, the Reorder Buffer rapidly fills with stalled instructions, forcing the execution unit to wait out the agonizing <strong>100-nanosecond</strong> latency of DRAM.</p><p>Because a modern processor operates near <strong>5 GHz</strong>, a single DRAM access wastes <strong>500 clock cycles</strong>. If the CPU possesses a decode width of 8 instructions per cycle, the penalty is severe. The processor throws away over <strong>4,000 potential instruction executions</strong> per memory hop. Thus, pointer chasing forces massive CPUs to operate at a fraction of their theoretical throughput.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6USY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6USY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 424w, https://substackcdn.com/image/fetch/$s_!6USY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 848w, https://substackcdn.com/image/fetch/$s_!6USY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 1272w, https://substackcdn.com/image/fetch/$s_!6USY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6USY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:407687,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.khola.blog/i/198645179?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.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_!6USY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 424w, https://substackcdn.com/image/fetch/$s_!6USY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 848w, https://substackcdn.com/image/fetch/$s_!6USY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 1272w, https://substackcdn.com/image/fetch/$s_!6USY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2288b4ff-0938-4cce-9c37-91d02c5fbfcd_3000x1500.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>The Jungle Walk Mental Model</strong></h3><p>Imagine driving on a straight highway where you speculatively look ahead and accelerate. The CPU prefetcher is your cruise control, bringing the road ahead into view before you reach it. Pointer chasing is like walking through a dense jungle with a machete. You cannot see the next step until you clear the immediate brush. Your speed is restricted to how fast you clear each step, forcing your massive out-of-order cores to stand idle.</p><h2><strong>The Bridge: How Environments Map to Silicon</strong></h2><p>The penalty of pointer chasing extends far beyond isolated CPU cache misses; it fundamentally dictates the failure modes of distributed edge infrastructure. An environment frame (or a closure) is a massive, deeply nested graph of pointers scattered across the heap.</p><p>Serverless platforms like AWS Lambda and Cloudflare Workers promote a strict stateless execution model. However, to bypass the extreme latency of cold starts, these platforms maintain warm execution environments by reusing the underlying container or V8 isolate across multiple sequential invocations. When a V8 isolate keeps a closure &#8220;warm&#8221;, it is effectively keeping that massive, scattered pointer graph alive. When the runtime must traverse this graph (either during execution or garbage collection sweeps), it defeats the CPU&#8217;s hardware prefetcher. Simultaneously, the sheer volume of retained state shatters the memory limits of the serverless container.</p><h3><strong>The Stale Air Lock Mental Model</strong></h3><p>Serverless warm environments are like a submarine air lock reused without flushing. The global frame is the main chamber, whereas the local handler invocation is the inner chamber. If stale credentials or closures are left in the main chamber, the next occupant breathes toxic air, inheriting the corrupted, recirculated state.</p><h3><strong>AWS Lambda Closure Scope Retention</strong></h3><p>A prominent pathology involves aggressively caching data in the global scope. In one documented incident, an engineering team deployed an image generation pipeline on AWS Lambda by initializing asynchronous callbacks outside the handler. Under sustained load, the closures created during each invocation captured strong references to massive buffer arrays.</p><p>Because the global environment frame retained strong bindings to these scattered closures, the V8 garbage collector was entirely blocked from reclaiming the memory. The Resident Set Size climbed relentlessly with each warm invocation until the container exhausted its <strong>5 GB memory limit</strong> and was terminated via SIGKILL. The resolution required strictly scoping mutable arrays to the local execution frame inside the handler, ensuring complete destruction upon function termination.</p><h3><strong>Cloudflare Workers Credential Bleed</strong></h3><p>State bleed also corrupts configuration security. On March 21, 2025, Cloudflare&#8217;s R2 object storage experienced a massive global outage caused by an architectural failure to strictly isolate global environment frames. During a routine key rotation, an engineering team inadvertently pushed new authentication credentials to a development instance instead of production.</p><p>When the old credentials were deleted from the backend, the production Workers were left holding a stale, globally bound context frame. Because the Worker reused its warm environment, it continued attempting to authenticate using the deleted keys. The resolution required deploying updated credentials to force the instantiation of new environment frames.</p><h2><strong>Bridging the Abstraction Gap</strong></h2><p>Ultimately, physical hardware realities dictate high-performance software architecture. Lisp&#8217;s elegant functional model has not failed, but it breaks down completely in hot-path, high-throughput data processing. Tree structures and closures remain perfectly valid for high-level business logic where the network is the actual bottleneck.</p><p>Nevertheless, the memory wall mandates contiguous memory arrays and explicit Data-Oriented Design (DOD) for performance-critical execution. Flat buffers and static memory layouts respect the physical thermal grid. In summary, if hot-path software abstraction ignores the hardware substrate, the inevitable outcome is a massive spike in latency.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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[Designing Data-Intensive Applications in 2026: An Architectural Retrospective
]]></title><description><![CDATA[A definitive review of Martin Kleppmann's foundational text, updating its distributed systems theory for the modern era of NVMe storage, unified lakehouses, and orchestrated sagas.]]></description><link>https://www.khola.blog/p/designing-data-intensive-applications</link><guid isPermaLink="false">https://www.khola.blog/p/designing-data-intensive-applications</guid><dc:creator><![CDATA[Nitin Khola]]></dc:creator><pubDate>Thu, 14 May 2026 03:18:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mh-h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mh-h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mh-h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 424w, https://substackcdn.com/image/fetch/$s_!mh-h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 848w, https://substackcdn.com/image/fetch/$s_!mh-h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 1272w, https://substackcdn.com/image/fetch/$s_!mh-h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mh-h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic" width="304" height="398.848" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:656,&quot;width&quot;:500,&quot;resizeWidth&quot;:304,&quot;bytes&quot;:62187,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.khola.blog/i/197620339?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mh-h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 424w, https://substackcdn.com/image/fetch/$s_!mh-h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 848w, https://substackcdn.com/image/fetch/$s_!mh-h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 1272w, https://substackcdn.com/image/fetch/$s_!mh-h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aff54a1-8d8d-4acb-9a35-fe5903d22b17_500x656.heic 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Martin Kleppmann&#8217;s <em>Designing Data-Intensive Applications</em> is basically required reading for backend engineering. The core premise still holds up: data volume, complexity, and velocity constrain architecture far more than raw CPU cycles.</p><p>But hardware doesn&#8217;t stand still. Reading the book in 2026 requires updating the physical variables Kleppmann used in his assumptions. When you swap in modern NVMe storage and unified compute engines, the structural trade-offs he outlines shift significantly. Here is a look at what actually survives contact with modern production infrastructure.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3><strong>1. Storage: The Metal Layer</strong></h3><p>Kleppmann dedicates a lot of space to the trade-offs between the traditional B-Tree and the Log-Structured Merge-tree (LSM-tree).</p><p>The B-Tree updates fixed-size logical disk pages in-place. DDIA correctly points out why this was a problem on magnetic hard disk drives (HDDs). Modifying a small record meant reading an entire page into memory, updating it, and writing it back to random locations. Because HDDs rely on mechanical arms, random seeks killed your IOPS.</p><p>LSM-trees bypassed this by turning random writes into sequential logs. Data is appended to a Write-Ahead Log and a memory buffer, then flushed to disk as immutable Sorted String Tables. It solved the HDD write bottleneck but introduced the compaction tax. Background compaction burns CPU and saturates disk I/O, which causes unpredictable tail latency spikes.</p><p><strong>The 2026 Reality:</strong> The modern data center runs on enterprise NVMe SSDs. These drives use highly parallel flash channels that largely neutralize the performance gap between sequential and random writes.</p><p>More importantly, modern enterprise SSDs have internal hardware controllers that perform transparent compression directly on the physical I/O path. If you use a modern B-Tree variant that logs zero-padded delta updates, the NVMe hardware instantly compresses the zeroes away. This drops the write amplification of the B-Tree from over 200x down to roughly 20x.</p><p>For general-purpose workloads today, the B-Tree is usually the better default. You get predictable read performance without paying the LSM compaction tax, because the hardware solved the random-write problem for you.</p><h3><strong>2. Distributed Data: The Network Layer</strong></h3><p>When dealing with distributed transactions, DDIA covers coordination protocols like Two-Phase Commit (2PC). In 2PC, a coordinator asks all participating nodes to place pessimistic locks on database resources before committing.</p><p>While the book acknowledges the performance hit of 2PC, its blocking nature is a complete non-starter in modern async architectures.</p><p><strong>The 2026 Reality:</strong> Today&#8217;s infrastructure relies heavily on long-running AI workflows and agent swarms. A single workflow might take hours to resolve. You cannot hold synchronous database locks across a distributed cluster for hours without causing complete system gridlock.</p><p>The industry has largely abandoned strong global consistency in favor of eventual consistency. We rely on Orchestrated Sagas and the transactional outbox pattern. You isolate the transaction locally, commit it, and publish an event to trigger the next step. There are no distributed locks held across service boundaries.</p><h3><strong>3. Derived Data: The Unbundling Layer</strong></h3><p>One of the best concepts in DDIA is unbundling the database. Instead of treating a single RDBMS as the system of record and fighting to keep caches in sync, you treat an append-only event log (like Kafka) as the source of truth. The database and search indexes are just materialized views derived from that log.</p><p>To handle analytical workloads in this model, DDIA discusses the Lambda Architecture. This involves maintaining a slow batch pipeline for accuracy and a fast stream pipeline for real-time approximation.</p><p><strong>The 2026 Reality:</strong> In practice, Lambda was an operational nightmare. You had to write, debug, and maintain your business logic twice across two different frameworks. That pattern is dead.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9hdP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9hdP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 424w, https://substackcdn.com/image/fetch/$s_!9hdP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 848w, https://substackcdn.com/image/fetch/$s_!9hdP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 1272w, https://substackcdn.com/image/fetch/$s_!9hdP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9hdP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png" width="1456" height="664" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:664,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:348555,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.khola.blog/i/197620339?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.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_!9hdP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 424w, https://substackcdn.com/image/fetch/$s_!9hdP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 848w, https://substackcdn.com/image/fetch/$s_!9hdP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 1272w, https://substackcdn.com/image/fetch/$s_!9hdP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9412d128-f382-4939-bc65-f33750dc13cd_3316x1512.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The maturation of unified execution models like Apache Flink operating over Lakehouse formats like Apache Iceberg has eliminated the need for it. &#8220;Batch&#8221; is now just treated as a bounded stream operating over a finite dataset. You get ACID transaction guarantees directly on top of scalable object storage. You write the pipeline once, and it handles both real-time ingestion and historical batch queries using snapshot isolation.</p><h3><strong>Final Thoughts</strong></h3><p>DDIA is still the best baseline we have for distributed systems theory. The abstractions are correct. But as engineers, we can&#8217;t treat the implementation details as dogma. The physical hardware dictates the architecture. Update the hardware assumptions, and the correct architecture changes with it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.khola.blog/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 Khola.Blog! 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>