<?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[Iouri Khramtsov]]></title><description><![CDATA[Iouri Khramtsov]]></description><link>https://www.i-kh.net</link><image><url>https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png</url><title>Iouri Khramtsov</title><link>https://www.i-kh.net</link></image><generator>Substack</generator><lastBuildDate>Sun, 11 Oct 2026 12:31:17 GMT</lastBuildDate><atom:link href="https://www.i-kh.net/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Iouri Khramtsov]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[iourikhramtsov@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[iourikhramtsov@substack.com]]></itunes:email><itunes:name><![CDATA[Iouri Khramtsov]]></itunes:name></itunes:owner><itunes:author><![CDATA[Iouri Khramtsov]]></itunes:author><googleplay:owner><![CDATA[iourikhramtsov@substack.com]]></googleplay:owner><googleplay:email><![CDATA[iourikhramtsov@substack.com]]></googleplay:email><googleplay:author><![CDATA[Iouri Khramtsov]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Estimating software projects without fooling yourself]]></title><description><![CDATA[There are people who&#8217;ll tell you that you can&#8217;t or shouldn&#8217;t estimate software work, to the point of outright refusing it. I fundamentally disagree with that.]]></description><link>https://www.i-kh.net/p/estimating-software-projects</link><guid isPermaLink="false">https://www.i-kh.net/p/estimating-software-projects</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Tue, 29 Sep 2026 23:08:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GCe8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are people who&#8217;ll tell you that you <a href="https://www.seangoedecke.com/how-i-estimate-work/">can&#8217;t</a> or <a href="https://www.youtube.com/watch?v=QVBlnCTu9Ms">shouldn&#8217;t</a> estimate software work, to the point of <a href="https://news.ycombinator.com/item?id=18487253">outright refusing to do it</a>. I fundamentally disagree with that.</p><p>In reality, businesses have to juggle tradeoffs, deadlines, and limited resources, and &#8220;it&#8217;ll get done when it gets done&#8221; doesn&#8217;t help decide whether to build feature A or feature B. Or how many people you&#8217;d need to finish the work by May.</p><p>That said, getting a decent estimate is hard, especially for a multi-quarter project. I&#8217;ve tried a number of things over my 15 years in software, with results ranging from spectacularly wrong to actually not too bad. And, based on the last few years, I think I&#8217;ve settled on something that works OK-ish. </p><p>This involves two components:</p><ul><li><p>Using the right methodology to get to the initial guess, and</p></li><li><p>Layering in the right amount of uncertainty.</p></li></ul><p>This post is meant to be a companion piece (sort of Part 2.5) for my <a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-1">Intro to Project Management for Developers</a> series, though you don&#8217;t have to read the rest of the series before reading this post.</p><h2>What doesn&#8217;t work</h2><p>There are two approaches that I&#8217;ve seen fail repeatedly, both producing wild underestimates.</p><p>The first one is: any guess that&#8217;s based on initial gut feel, especially when not backed by experience delivering software end-to-end. I&#8217;ve often seen it from &#8220;business&#8221;-side people who don&#8217;t know what it takes to deliver software. But it&#8217;s also very common among developers who haven&#8217;t managed a project end-to-end, because they picture just coding the core functionality changes and miss the other 90% of the work needed to complete the project. This is how you get an estimate of &#8220;a couple months&#8221; on a project that ends up taking a year.</p><p>The second approach that doesn&#8217;t work, surprisingly, is breaking up the delivery into small steps, each a few hours to a few days long, estimating them individually, and then adding them up.</p><p>Well, actually, it works pretty well for projects that take a single developer a month or so to complete. But it often fails for larger projects. This happens for a couple of reasons:</p><ol><li><p>No matter how thoroughly you <a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-2">design and plan</a> the project, you will always have course corrections, inter-team frictions, missed or changed requirements, and other surprises that consume a lot of energy but are difficult to size upfront.</p></li><li><p>Sizing this way is a lot of work. Most people get tired after they size the first couple sprints, give up, and go with their gut feel for the rest of the project. Kind of like drawing this owl:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GCe8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GCe8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 424w, https://substackcdn.com/image/fetch/$s_!GCe8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 848w, https://substackcdn.com/image/fetch/$s_!GCe8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 1272w, https://substackcdn.com/image/fetch/$s_!GCe8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GCe8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png" width="530" height="453" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:453,&quot;width&quot;:530,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Meme: How to draw an owl&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Meme: How to draw an owl" title="Meme: How to draw an owl" srcset="https://substackcdn.com/image/fetch/$s_!GCe8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 424w, https://substackcdn.com/image/fetch/$s_!GCe8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 848w, https://substackcdn.com/image/fetch/$s_!GCe8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.png 1272w, https://substackcdn.com/image/fetch/$s_!GCe8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3e972c2-502f-4570-9007-7a56dfdd6b81_530x453.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ol><p>To be clear, with the second approach, you&#8217;d still likely get a better estimate than with the first. But unless you&#8217;re really thorough, don&#8217;t be surprised if your estimate is off by an order of magnitude.</p><h2>So, how do you estimate a large project?</h2><p>The best method I&#8217;ve found so far is to use comparable projects. This is supported by research (e.g. <a href="https://www.researchgate.net/publication/3187904_Estimating_software_project_effort_using_analogies">this</a> and <a href="https://www.sciencedirect.com/science/article/abs/pii/S0950584998000974">this</a>) and has been replicated across industries&#8212;for example, by Flyvbjerg and Gardner in their book <a href="https://www.penguinrandomhouse.ca/books/672118/how-big-things-get-done-by-bent-flyvbjerg-and-dan-gardner/9780771098437">How Big Things Get Done</a>.</p><p>The approach goes something like this: suppose you&#8217;re estimating a new feature that&#8217;s similar to one you built last year. Last year&#8217;s project took six months with four developers, or about 24 developer-months total.</p><p>Say about a quarter of that effort went into the general feature code, while the rest went into integrating with six banks, each with its own quirks and idiosyncrasies. Your new feature touches the same front-ends and back-ends but only needs four bank integrations instead of six.</p><p>A rough estimate for the new feature could then be:</p><ul><li><p>General feature work: ~6 developer-months (same as before)</p></li><li><p>Bank-specific work: ~12 dev-months (4/6 of the previous ~18 dev-months)</p></li><li><p>Total: ~18 dev-months</p></li></ul><p>You can refine this further; for example, if you&#8217;re really confident that you can reuse some bank integration code and save one dev-month, feel free to subtract that. Though in practice, the uncertainty on this estimate will be at least ~25% (see next section), so there&#8217;s no point in stressing over any tiny adjustments.</p><p>The main benefit of this approach is that most of the time it automatically accounts for the course corrections, inter-team frictions, and other surprises that you&#8217;d have a hard time sizing when estimating bottom-up from small parts.</p><p>But what if you don&#8217;t have such a great comparable? Then you&#8217;d have to reach for less similar projects and add appropriate adjustments. Or maybe look at other teams&#8217; comparable projects, or other projects from your experience at other companies. If all else fails, you can break up the project into coarser chunks and estimate each chunk using comparables. But be aware that once you do that, you go back to missing some of the surprises that inevitably arise when you try to fit the various parts together.</p><h2>Converting the estimate to a range</h2><p>So now you have a decent initial guess. But in reality, all estimates come with a range or an uncertainty level, and now we have to figure out the right uncertainty level for this project.</p><p>This is where we have to leave any pretense of science or rigorous methodology behind and go just off past experience.</p><p>And from my experience, I&#8217;d group the projects like this:</p><ul><li><p><strong>Known territory:</strong> You have a solid comparable and you&#8217;re touching mostly the areas where your team regularly works. Your estimate is probably off by around &#177;25%.</p></li><li><p><strong>Something kinda new:</strong> You don&#8217;t have a good comparable, but you&#8217;re still mostly on familiar ground. Maybe you&#8217;re building a new kind of feature, integrating with teams or APIs you haven&#8217;t worked with, or setting up new infrastructure. In this case, the actual work will likely be up to 2x the original estimate.</p></li><li><p><strong>Outer wilds:</strong> You&#8217;ve never done this before and you had to piece your estimate together from POC outcomes or small individual work items. You&#8217;re likely undersizing by at least 4x. From past experience, a guess of 4-8x the original estimate is likely closer to reality.</p></li></ul><p>With a more concrete example of the payroll feature above, I&#8217;d present the estimate like this in each situation:</p><ul><li><p><strong>Known territory:</strong> &#8220;It should probably take 3-4 people a couple of quarters to do this, based on how long it took us to make {other feature}.&#8221;</p></li><li><p><strong>Something kinda new:</strong> &#8220;3-4 people in two or three quarters, depending on what kind of surprises we encounter and what we can reuse.&#8221;</p></li><li><p><strong>Outer wilds:</strong> &#8220;We&#8217;ve never done anything like this. On the surface, this doesn&#8217;t look like much, but I&#8217;ve seen projects like this really blow up. I wouldn&#8217;t be surprised the whole team ends up taking a year or two to finish this.&#8221;</p></li></ul><p>&#8230;with the last estimate likely leading to a lively discussion on how to limit the scope and deliver at least some sort of useful result as soon as possible.</p><h2>Alternatively, you can give estimates with an uncertainty level</h2><p>Sometimes, instead of ranges, you might be answering a question like &#8220;Can we finish this by March next year?&#8221;</p><p>You can apply the same methodology and check where exactly March falls relative to the estimate&#8217;s range&#8212;though don&#8217;t forget to offset it from when you&#8217;d start the work, not from right now.</p><p>Then, your responses could be something like:</p><ul><li><p>&#8220;That&#8217;s really unlikely; other similar features have taken us longer.&#8221; Or,</p></li><li><p>&#8220;It&#8217;s plausible, but only if everything goes perfectly and the whole team works on it. It would be safer if we reduce the scope.&#8221; Or,</p></li><li><p>&#8220;We almost certainly can, but I&#8217;d prefer to have 4-5 people on this just to be sure we make it.&#8221; Or,</p></li><li><p>&#8220;Yes, definitely.&#8221;</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Like what you&#8217;ve read? Subscribe for more</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Final thoughts</h2><p>So ultimately, yes, the estimation is imprecise and often wrong. But that doesn&#8217;t mean that you can&#8217;t help the decision-makers by doing your best. If you ground your estimates in reality and honestly communicate the uncertainty level, you can give people useful information without pretending to know more than you do.</p><p>And that&#8217;s really the goal: not to predict the future perfectly, but to make better decisions with the information you have.</p><p></p>]]></content:encoded></item><item><title><![CDATA[Neat trick to make big PRs readable: reslicing them into small commits]]></title><description><![CDATA[It&#8217;s pretty hard to review a PR with a +4k/-1k changeset that touches 72 files.]]></description><link>https://www.i-kh.net/p/neat-trick-to-make-big-prs-readable</link><guid isPermaLink="false">https://www.i-kh.net/p/neat-trick-to-make-big-prs-readable</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Sat, 26 Sep 2026 12:45:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It&#8217;s pretty hard to review a PR with a +4k/-1k changeset that touches 72 files. PRs like that used to be rare, maybe if there was a large refactor or an upgrade that had to go in all at once. But now I run into them regularly.</p><p>Last week, when AI wrote two of those for me and I had to review them, I decided to try a new trick.</p><p>Well, the trick is actually old; I first saw it about seven years ago when I started working as a Tech Lead at Vena Solutions. Back then, our VP of Architecture really liked refactoring and cleanup, which often produced large PRs. To make those PRs palatable to us, he organized them into neat, very focused individual commits with one specific change in each commit, something like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">f8ee9aa   Rename class BadlyNamedClass to BetterNamedClass
18c240f   Simplify logic in BetterNamedClass.SomeMethod()
1a4acf0   Update tests for BetterNamedClass.SomeMethod()
8b10bc0   Clean up unused imports
          ...(etc)...</code></pre></div><p>Some commits had a lot of lines changed, but it was the same change on each line (e.g. rename <code>SomeThing</code> to <code>OtherThing</code>). Other commits had a specific narrow focus, like a tweak to a complex algorithm. Each individual commit didn&#8217;t have to be compilable or pass tests by itself; it just had to tell the next chapter in the overall story of what the PR was doing.</p><h2>You can get AI to reslice an existing PR</h2><p>That&#8217;s the new trick I tried: getting the AI to do that to a pre-existing PR. </p><p>I would have never done this by hand myself. But AI has infinite patience (well, as long as the tokens last), and it had no problem tearing apart all 4k lines of code and carefully piecing them together into 20-ish commits. It wasn&#8217;t perfect, but it was good enough  that reviewing was a lot easier.</p><p>So then I turned it into a skill (below); after using it on several more PRs, I think from now on I&#8217;ll be doing it every time just so that I can read the PRs myself.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">---
name: restack-pr-commits
description: 'Reorganizes the PR as a series of easily reviewable commits.'
argument-hint: 'for pull request &lt;PR URL&gt;'
---

## Overview

The goal of this skill is to turn a large, hard-to-review 
PR into a series of commits that are each individually easy 
to review. The commits, once fully stacked, must match the 
original PR character-for-character. 

Each commit is "easily reviewable" if it introduces a 
relatively straightforward change. It can be a commit 
affecting a large number of lines that does something simple 
(e.g. rename a variable or clean up unused imports), 
or a commit that adds a specific tricky concept in one 
file, or something in between. Generally, new tests 
should be added separately from the newly added code, 
but a change to functionality can have a single commit 
spanning both the main code and the tests.

Each individual commit doesn't need to pass the build or 
the tests; the primary criterion is reviewability.

## Steps

You should have been provided a PR to work on. If you 
haven't, stop and ask for it.

Make sure that you're clear on which branch the commits 
are based on. We'll call this branch the "base branch".
This would usually be the repo's main branch (called 
`master`, `develop`, `dev`, or `main` - this depends on 
the repo) but it may not always be the case. If it's 
unclear what the base branch is, stop and ask.

1. Check out the PR's branch locally. Make sure you're
   on the latest version of it. Once done, your 
   current branch should be the PR's branch. We'll
   call it `{current-branch}` from now on. If during 
   this step you cannot use `git` or `gh`, stop and let 
   the user know, as you won't be able to proceed further.
2. Make a backup of the current branch.
    - Do: 
        - `git checkout -b {current-branch}-backup`
        - `git checkout {current-branch}`
        So that you end up with the backup of the current 
        branch, but you'll still be working on the current 
        branch. DO NOT drop the backup branch; we will 
        leave it forever as a backup, so don't clean it up.
3. Come up with the commit breakdown.
    - Review the contents of the PR, the PR description, 
      and any relevant documentation to fully understand 
      the changes.
    - Come up with several distinct ideas for how to 
      split up the PR into easy-to-review commits.
    - Come up with the criteria to figure out which of 
      the choices is best.
    - Review each of the proposals for the split. Evaluate 
      them against your criteria, critique them, and rank 
      them against each other.
    - Based on your critiques, update each of the options 
      for the split.
    - Critique and rank these options again and come up 
      with the final ranking.
    - Come up with the final recommendation for how to 
      split the PR into commits. The final recommendation 
      may be any combination of the proposed 
      recommendations based on your analysis.
4. Figure out a strategy you'll use for verifying that 
   the final result matches the current PR 
   character-for-character. Make appropriate preparations 
   as necessary.
5. Rebuild the PR as a series of commits on top of the 
   base branch as per your proposal. After each commit, 
   verify that the commit has added exactly what you 
   think it should have added and that there's nothing 
   missing and no copying errors. If there are any issues, 
   amend the commit as needed. Each individual commit
   doesn't need to pass the build or the tests, so don't 
   rerun those between the commits. 
6. Verification: when done, verify that the final 
   result matches the current PR 
   character-for-character. If not, fix any commits 
   as needed. 
7. Rerun the build and the tests as needed. 
8. Force-push the changes to the origin so that the 
   PR now looks like a series of new commits.

Do not clean up the backup branch; we may need it 
later if there were any issues.</code></pre></div><h2>But what about stacked PRs?</h2><p>If you aren&#8217;t familiar with stacked PRs, <a href="https://docs.github.com/en/pull-requests/get-started/about-stacked-prs">this GitHub page</a> gives a decent overview.</p><p>They&#8217;re certainly an option, but I find that before starting the implementation, it&#8217;s not always clear which PR should be the base PR, and sometimes after a lot of fixes and follow-up tweaks, the stack needs to get reorganized a lot, which is annoying to do when you&#8217;re dealing with PRs instead of commits.</p><p>And it&#8217;s a lot more practical to reslice a 4k LOC PR into 20 commits rather than 20 stacked PRs.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Like what you&#8217;ve read? Subscribe for more:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[If AI coding is lowering your code quality, you’re not managing quality right]]></title><description><![CDATA[One common take on the coding agents that I see goes something like this: &#8220;Sure, AI helps you output more code, but won&#8217;t the quality suffer?&#8221;]]></description><link>https://www.i-kh.net/p/if-ai-coding-is-lowering-your-code</link><guid isPermaLink="false">https://www.i-kh.net/p/if-ai-coding-is-lowering-your-code</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 14 Sep 2026 12:15:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One common take on the coding agents that I see goes something like this: &#8220;Sure, AI helps you output more code, but won&#8217;t the quality suffer?&#8221;</p><p>It certainly will if you just blindly merge the PRs and send them off to prod. But if you take a thoughtful, layered approach to managing quality, I find that it&#8217;s possible to not just keep the number of bugs stable but actually reduce it&#8212;while still increasing the output by 2-2x.</p><p>Many of these defensive layers are pretty much the same as before Claude/Copilot/Codex/etc. (though they&#8217;re made easier now by AI), while others are new. Here&#8217;s a defensive setup that I&#8217;ve seen successfully used in practice, both on my team and elsewhere.</p><h2>Layer 1: Getting the requirements right</h2><p>One of the biggest surprises after <a href="https://www.i-kh.net/p/my-spec-first-workflow-for-ai-coding">I started using spec-driven development</a> was the drop in bugs in the freshly written code. Before spec-driven development, when building, e.g., a new feature, the teams I was on often spent up to a third of the total effort on the post-development &#8220;polishing,&#8221; i.e., discovering and fixing various bugs. Many of these bugs occurred either because we didn&#8217;t foresee certain interactions and edge cases, or because the developer was tired that day and didn&#8217;t put in enough thought, or because the designer or PM didn&#8217;t think through certain scenarios. Some of these bugs were missed and ended up in production.</p><p>After I started using spec-driven development, the number of these bugs in my code sharply dropped, and I&#8217;ve seen the same drop for some (but not all) of my teammates. As far as I can tell, the main cause of this drop is one specific step in the process: having the AI review the requirements or the tech design and find any gaps, edge cases, unexpected interactions with the existing code, or other similar problems.</p><p>The AI doesn&#8217;t get tired and, when prompted right, is a lot less likely to give up hunting for potential issues. If anything, it can sometimes be overzealous, and I have to carefully review its proposed edits to the requirements to make sure that it doesn&#8217;t invent any issues that aren&#8217;t there.</p><h2>Layer 2: Unit tests at &gt;95% coverage</h2><p>Coding agents now make test-driven development (TDD) trivial to the point where there&#8217;s no reason not to do it. However, it needs to be done right: you don&#8217;t want the agent to blindly write passing tests for any bugs it just added to the code. So the best planning and implementation skills I&#8217;ve seen usually follow this pattern:</p><ul><li><p>Instruct the agent to think through the test scenarios and test cases based on the requirements,</p></li><li><p>Write the test cases,</p></li><li><p>Write the implementation,</p></li><li><p>Test the implementation against the test cases and fix any issues that come up,</p></li><li><p>Maybe backfill any remaining coverage gaps&#8212;but again, keeping the requirements in mind.</p></li></ul><p>Also, with the agents writing the tests, there&#8217;s no excuse not to shoot for near-universal coverage or to wait on backfilling any missing unit tests.</p><h2>Layer 3: Manual testing</h2><p>There&#8217;s still no substitute for a human (you, QA, PM, or someone else) actually trying out the feature, going through all the edge cases, and seeing whether everything works as expected or whether you need to make changes.</p><p>These manual tests can take a while, especially if the test scenarios take some effort to set up. This is one of the steps that so far has seen only modest gains in productivity, and it&#8217;s the main reason that my output has increased only 2-3x instead of something like 10x. Though now that I think about it, there may be a few opportunities for automation here that I&#8217;ve missed.</p><h2>Layer 4: Extensive automated end-to-end tests</h2><p>End-to-end (E2E) tests are arguably the most important tests in the codebase because they verify that new changes haven&#8217;t broken any existing functionality as experienced by the end user. Ideally, they&#8217;d run on the PRs, in the test/stage environments, and in production after every deployment. Ideally, they&#8217;d also be maintained by the same developers who write regular code, but I understand that some organizations aren&#8217;t really set up for that.</p><p>AI does make it easier to write E2E tests, but to do that effectively, it needs access to the tools or MCP servers that let it debug test failures&#8212;e.g., a browser tool or MCP access to the logs. However, it&#8217;s important to keep in mind that E2E tests aren&#8217;t a substitute for manual testing because they&#8217;re just a rough, incomplete check that nothing important broke.</p><h2>Layer 5: Code quality passes by AI</h2><p>I find that coding agents aren&#8217;t great at following complex instructions in <code>AGENTS.md</code> or <code>CLAUDE.md</code>. But they do pretty well if you add a separate pass to find and fix specific issues. These can be:</p><ul><li><p>Security issues,</p></li><li><p>Finding overcomplicated or duplicated code,</p></li><li><p>Compliance with naming, file organization, or formatting rules,</p></li><li><p>A general code review pass to find any issues with the logic,</p></li><li><p>Overly long comments written in AI-ese instead of regular English,</p></li><li><p>Any other specific things that you&#8217;d like to find and fix.</p></li></ul><p>If added to the planning or implementation skills, these can be pretty much &#8220;free&#8221; additions, adding maybe 5-15 min to the implementation time with no additional attention required.</p><p>They can be also added to the PR reviews if you prefer to take a look at the comments before applying any fixes.</p><h2>Layer 6: PR reviews by humans and AI</h2><p>I think I&#8217;m becoming convinced that for minor tweaks and simple bug fixes, human reviews can become optional. Provided that other defensive layers are still in place.</p><p>But for complex changes, I find that it&#8217;s still necessary to review AI-written code. I still regularly find big-picture mistakes, missed adverse interactions with other features, overcomplicated or suboptimal implementations, and other problems. Not to mention weird word choices like &#8220;mint&#8221; instead of &#8220;generate&#8221; or &#8220;stamp&#8221; instead of &#8220;set.&#8221;</p><p>AI code reviews have also been a really great addition. On my current team, we run both Claude and Cursor reviews on the PRs, and surprisingly, each of them finds different problems. You can also add other custom reviews from various angles, like security, efficiency, interactions with other repos, and so on, though be aware that AI can be overly nitpicky in its reviews, so it&#8217;s important to also have a pass where another agent prunes the proposed AI-generated PR comments that aren&#8217;t actually meaningful.</p><h2>Layer 7: Monitoring and alerting</h2><p>Once the code is in production, at a minimum, it&#8217;s good to have someone periodically scroll through the logs or watch any user recordings in something like Fullstory, or review various dashboards that track error rates, latencies, and other issues.</p><p>Even better would be an error tracking service like Sentry or GCP&#8217;s Error Reporting that detects and deduplicates errors.</p><p>The best approach, however, would be to then have Claude/Cursor/whatever auto-diagnose these errors, figure out the root cause, and make PRs with the proposed fix.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Like what you see? Subscribe for more:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2>Conclusions</h2><p>I&#8217;m sure I&#8217;ve missed other important components of maintaining high quality, but the main idea is that with the right set of defensive layers, the increased output doesn&#8217;t have to come at the cost of reliability. If anything, coding agents now make it cheaper to add more and deeper checks than before: more tests, more review passes, faster diagnosis of production issues.</p><p>So if you&#8217;re sufficiently focused on quality, I think it&#8217;s entirely possible to double the delivery speed while keeping the bugs under control. Or maybe even reducing them.</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[What to do when your coworker uncritically copy-pastes AI]]></title><description><![CDATA[Or, how to politely discourage others from becoming AI meat proxies]]></description><link>https://www.i-kh.net/p/what-to-do-when-your-coworker-uncritically</link><guid isPermaLink="false">https://www.i-kh.net/p/what-to-do-when-your-coworker-uncritically</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 07 Sep 2026 22:28:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It finally happened to you: you asked your coworker a question and they gave you an answer that&#8217;s obviously copy-pasted AI output. Or maybe they&#8217;ve sent you a document they&#8217;ve &#8220;written&#8221;, but it reads like AI slop. Or (for software engineers), maybe your coworker just started leaving comments on your code that look like unfiltered AI output.</p><p>You&#8217;re starting to get annoyed, but you aren&#8217;t sure what to do. Should you tell them off and cause a confrontation? Send them a link to <a href="https://noslopgrenade.com/">noslopgrenade.com</a> or <a href="https://dontpastetheai.com/">dontpastetheai.com</a> and come off as passive-aggressive? Politely try to hint that maybe you were hoping for a different answer?</p><p>I&#8217;ve run into this situation a few times and I think I have an approach that works reasonably well.</p><h2>Warning: this may not work for everyone</h2><p>Admittedly, this approach works best if you&#8217;re the person&#8217;s manager. And you should probably avoid it if the copy-paster is a thin-skinned person who holds a lot of power over you.</p><p>Between those two extremes, you&#8217;re more likely to succeed if you&#8217;re in a more senior position, or have accrued credibility with the person, or if your coworker has signaled that they&#8217;re very open to feedback.</p><h2>First, identify the actual problem</h2><p>Ask yourself: what specifically about the incident caused you inconvenience?</p><p>Was it that you had to read through a wall of text when a single sentence would have been enough, wasting your time and attention? Was the document confusing to read and follow? Did you have to wade through 10 comments on your code that obviously missed the context? Is it that you were hoping for their own opinion but now you aren&#8217;t even sure they&#8217;ve read the question?</p><p>Sometimes copy/pasted AI output isn&#8217;t actually a problem. For example, a couple of weeks ago, a co-worker of mine sent me a comment on my code that said &#8220;Claude Code says: {quotes Claude Code}. Do you think it&#8217;s worth checking out?&#8221; On the surface, that should have been annoying, but this coworker (1) is often right, and (2) is usually thorough in his work and reviews. So this comment was likely filtered from many others left by AI and probably contained a valid concern.</p><p>But suppose there&#8217;s an actual problem, and you&#8217;ve identified what it is.</p><h2>Next, bring this up with the coworker</h2><p>I usually open the conversation with something like:</p><blockquote><p>Hey {name}, are you open to some unsolicited feedback on {thing in question}?&#8221;</p></blockquote><p>Or some variation of that. This does a couple of things:</p><ul><li><p>The answer will probably be &#8220;yes&#8221;, and hopefully as a result they&#8217;d be at least partly open to the feedback.</p></li><li><p>You&#8217;re setting up an expectation that there&#8217;s some negative feedback coming so it doesn&#8217;t just drop on them unexpectedly.</p></li></ul><p>Next, follow the rules of constructive feedback:</p><ul><li><p>Be direct; don&#8217;t dance around the problem.</p></li><li><p>Concentrate on the behavior and its negative effect on you rather than concentrating on the other person.</p></li><li><p>If possible, prefer to use &#8220;I&#8221; statements like &#8220;I was confused&#8230;&#8221;, &#8220;I had to spend more time&#8230;&#8221; rather than accusatory &#8220;you&#8221; statements like &#8220;you made me waste time&#8221;. The feedback might be negative enough as it is, and phrasing it as &#8220;you&#8217;re bad&#8221; is an unnecessary extra slap in the face. Of course, sometimes it&#8217;s unavoidable.</p></li><li><p>Keep in mind that it&#8217;s not the use of AI in general that&#8217;s the problem, it&#8217;s this specific use that&#8217;s the problem.</p></li></ul><p>So your next message could be something like:</p><blockquote><p>When you give me unfiltered AI output as PR comments, I have to spend time figuring out whether each of the comments even makes sense. It would be a lot more helpful if you pre-filtered the AI findings yourself and left only those that you think actually apply.</p></blockquote><p>Or,</p><blockquote><p>I found that the document was confusingly organized: {add specific problems}, and I had a hard time following it. I think it would have been a lot clearer if it had&#8230; {specific suggestions}. In general, I find that AI is pretty bad at organizing documents, and I have to edit them myself afterwards.</p></blockquote><h2>The consequences</h2><p>I&#8217;ve had various responses from coworkers to this. One was very open to feedback, said thank you, and moved on. One was more defensive, but the feedback was eventually internalized and the issue did not reoccur.</p><p>Whatever happens, don&#8217;t get into an argument&#8212;it will only entrench the other person further in their views. You&#8217;ve left the message; you can move on now.</p>]]></content:encoded></item><item><title><![CDATA[Intro to project management for developers: Part 2 - Design and Planning]]></title><description><![CDATA[If you haven&#8217;t read Part 1, you may want to start there.]]></description><link>https://www.i-kh.net/p/intro-to-project-management-for-developers-2</link><guid isPermaLink="false">https://www.i-kh.net/p/intro-to-project-management-for-developers-2</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 07 Sep 2026 14:30:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>If you haven&#8217;t read <a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-1">Part 1</a>, you may want to start there.</em></p><p>Now that everyone&#8217;s clear what exactly needs to be done, it&#8217;s time to start on more thorough design and planning.</p><p>I&#8217;ve split this post into two parts:</p><ul><li><p><strong>Technical Design:</strong> addresses what the change should look like, and</p></li><li><p><strong>Planning:</strong> preparing to deliver the changes smoothly.</p></li></ul><p>But first&#8230;</p><h2>Why should you do technical design and planning?</h2><p>Again, some of you may be tempted to jump straight into building and figure things out as you go. That will work for a small deliverable that you&#8217;re doing by yourself. However, if you skip the design and planning for larger projects, you risk running into problems like this:</p><ul><li><p>Halfway through, it turns out you need another team to do something, and their backlog is full until the end of the quarter.</p></li><li><p>Mid-sprint you discover that one of the developers disagrees with you on the design. Now both of you need to stop your work and debate it. The rest of the team has to stop too because their work depends on the outcome of the debate.</p></li><li><p>The code that worked for the first two parts of the project doesn&#8217;t work for the third, and now you need to rewrite most of it.</p></li></ul><p>The job of technical design and planning is to discover issues like these early when they&#8217;re cheapest to address. It won&#8217;t prevent all surprises; you could still get last-minute feedback that the users are confused by the interface and end up having to rewrite it. But at least you can minimize the delays and rework from the foreseeable problems.</p><h2>Technical design</h2><p>With that in mind, when I go into technical design, my goals are:</p><ol><li><p>Uncover as many technical surprises and as much unexpected work as possible&#8212;plus any missed requirements.</p></li><li><p>Uncover any hidden dependencies, especially dependencies on other teams or outside vendors.</p></li><li><p>Make sure that the team is clear on what we&#8217;re doing and agrees with the approach.</p></li><li><p>Get a better sense for the size of the work, how many people are needed, and how it can be broken up and parallelized.</p></li></ol><p>We&#8217;re going to do this by diving deep into the design and, again, having some meetings.</p><h4>Discovering surprises and dependencies</h4><p>From everything I&#8217;ve tried so far, there isn&#8217;t really an easy way to do this except to go and design the system in detail. </p><p>To keep track of that, I usually start a technical design document. If your organization already has a technical design template, try to follow it; if not, feel free to start another document similar to the requirements one. I find the exact format doesn&#8217;t really matter, as long as the document is reasonably readable and follows basic principles of technical writing like putting the summary and most important information first, then gradually expanding into details.</p><p>In this document, start sketching out the system design in a bit more excruciating detail than you&#8217;d first think is necessary. Like, not the individual functions and classes, but maybe a level above that.</p><p>For example, in my recent project that delivered a new user-facing feature across several front-ends and back-end services, the technical design involved writing out:</p><ul><li><p>The full list of the front-ends and the full list of the back-end services involved, how each one would change, which new REST API endpoints would need to be created, request/response sketches, and what authentication would be used in each case.</p></li><li><p>A detailed sketch of how each of a couple dozen or so user flows would be handled by the system, including how it would move through the front-ends, back-ends, DBs, auth used, vendor interactions, and so on. Since the system involved moving around and submitting complex data structures, the design also included listing where each data field would come from and how we made sure that it was correct.</p></li><li><p>Any data model changes and data migrations, the exact list of the background jobs that would need to be present, and any notable infrastructure changes beyond the standard setup.</p></li></ul><p>Plus a few other details. </p><p>Other things worth including, depending on your situation:</p><ul><li><p>Expected scale, latency, and throughput.</p></li><li><p>Security, privacy, authentication, and permissions.</p></li><li><p>Any dependencies on other teams or vendors/partners. You&#8217;ll want to start conversations with them early.</p></li><li><p>Whether any organizational reviews need to be passed, such as security, legal, compliance, or architecture reviews.</p></li></ul><p>What&#8217;s the right level of detail to go into when writing everything out? Well, consider the earlier goals: we&#8217;re trying to uncover major surprises like unexpected work, dependencies, or difficult technical questions. So focus on the details where getting things wrong would cause substantial rework, delay, or a dependency surprise. Don&#8217;t overdesign details that are cheap to change later.</p><h4>Tracking open questions and risks</h4><p>Just as with the requirements, when writing a technical design, it&#8217;s good to keep an eye on spots where you&#8217;re not totally clear on the details. This could be either questions about requirements, or questions about how to implement something, or maybe questions you need to ask other teams, or architects, or vendors.</p><p>In these cases, write these down so you don&#8217;t forget them. And make sure to follow up on them.</p><p>Also, remember the Risks section from Part 1? Now is a good time to sit down and ask yourself: what are some of the ways the project can go wrong? These could result in more open questions or follow-up meetings.</p><h4>Getting the team on board</h4><p>As mentioned before, one of the goals of the design process is to make sure that all team members who&#8217;d be working on the project understand how it would be implemented and agree with the approach.</p><p>The best way to do that, I find, is to have a meeting with all project participants and walk them through what you have in mind so far. Then ask for questions or opinions and be genuinely open to feedback and criticism. Take those away, think them through, and update the document as needed.</p><p>In cases of major disagreement or concerns, I found it useful to have follow-up discussions with the person who brought them up, maybe even working with them over a few days or weeks to resolve the issues or update the designs.</p><h4>Simplifying the design</h4><p>As you&#8217;re working through the design, it&#8217;s worth periodically asking questions like:</p><ul><li><p>Is there a simpler way to do this? Or, do I even need to do this?</p></li><li><p>Now that I know the cost of this requirement, should we still do it?</p></li></ul><p>The latter question has often led to conversations with product managers or other decision makers who, after realizing the cost, ultimately said &#8220;you know what, maybe we don&#8217;t need this.&#8221;</p><h2>Planning</h2><p>I usually start transitioning to planning once the design starts stabilizing, though depending on the time constraints you may have to start planning out some pieces sooner.</p><p>Each organization has its own way to track large features/epics/projects together with their subtasks, and its own processes for refinement or planning. You&#8217;re more familiar with those than I am, so I won&#8217;t give you advice on how to use them. Instead, I&#8217;ll just give some general pointers for planning larger projects.</p><p>Unlike design, I found that it&#8217;s OK not to go too deep into planning upfront and instead take it sprint-by-sprint. That said, there are still a few questions that you&#8217;d need to answer before planning the first batch of work:</p><ol><li><p>What is the dependency between the different deliverables? Which ones are blocking&#8212;i.e. must be delivered first, before any work that depends on them?</p></li><li><p>Now that you know the design, what&#8217;s the total effort? Do you think you&#8217;d meet your deadlines? Should you go to your manager or other decision makers and renegotiate the scope, the timeline, or the resources (i.e. the number of people working on the project)?</p></li><li><p>If you have more than one person working on this project, can you parallelize things in a way that keeps everyone busy without any gaps or downtime?</p></li><li><p>There may still be surprises lurking; what&#8217;s the best way to uncover them as early as possible?</p></li></ol><p>For this purpose, I find it&#8217;s helpful to at least do a rough sizing of the various components of the project with the team, add some padding for the inevitable problems and unknowns, and sketch out what pieces should be delivered in the first few sprints.</p><h4>Integrating and deploying the work</h4><p>One of the questions that also needs to be addressed upfront is what your overall approach to integration and testing will be. By that I don&#8217;t just mean CI and automated tests (I assume that&#8217;s a given these days), but for the entire project as a whole.</p><p>I&#8217;ve seen projects delivered two ways:</p><ul><li><p><strong>Approach 1:</strong> Everyone writes various pieces separately, possibly coding/testing against pre-agreed interfaces. Then the entire system is put together, tested in the test environment, and then deployed to production.</p></li><li><p><strong>Approach 2:</strong> First, the thinnest possible sliver of end-to-end functionality is deployed to the test and production environments. Then everyone builds out the various pieces around it, doing integration testing in the full system as they go.</p></li></ul><p>From personal experience, Approach 2 is far superior. This is for a couple of reasons:</p><ul><li><p>Deploying to prod as soon as you can allows you to do end-to-end testing earlier, show the system to the prospective users earlier, and adjust course sooner. Also, some bugs show up only in the end-to-end tests; would you rather find them early in the project, or a week before launch?</p></li><li><p>Production deployment is often more complex than you&#8217;d first expect, especially in larger organizations and for large projects. You may have to wait for approvals, satisfy unforeseen requirements, or (in at least one case I&#8217;ve experienced) switch to an entirely new deployment method due to a recent directive by a CTO that you weren&#8217;t aware of until you tried to deploy. Ideally, you&#8217;d deal with these surprises early.</p></li></ul><p>For this reason, in the first couple of sprints on large projects, I prefer to focus not just on building out the initial critical pieces of code, but also on deploying shells of all components to production and making them demonstrate end-to-end connectivity.</p><h4>Pieces that often get missed</h4><p>When planning the work, even senior engineers sometimes forget that &#8220;Done&#8221; is not just when the code is written or the PR is merged, but when:</p><ul><li><p>Someone confirms in the test environment that the change does what it&#8217;s supposed to do,</p></li><li><p>If it doesn&#8217;t, any follow-up adjustments and fixes are made, and</p></li><li><p>The change is deployed to production, where it&#8217;s also proven to work as expected.</p></li></ul><p>Often these steps take nearly as much time and effort as the original code, so make sure to include them when planning both the individual tasks and larger components.</p><h2>How long should design and planning take?</h2><p>On shorter, simpler projects I&#8217;ve had design and planning take a day or two, plus one or two meetings with the team. For larger multi-quarter projects, I&#8217;ve had it take up to a couple of months with multiple follow-up meetings with various individuals.</p><h2>Moving on</h2><p>With the tech designs firmed up and the initial work planned out, now it&#8217;s time for the fun part: building.</p><ul><li><p>Next up, coming soon: <strong>Intro to</strong> <strong>project management for developers: Part 3 - Staying on top of delivery</strong></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Like what you&#8217;ve read? Subscribe for more:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Intro to project management for developers: Part 1 - Starting a project]]></title><description><![CDATA[As a software engineer, as you grow in seniority, at some point you may be asked to lead the delivery on a feature, an initiative, or a project of some sort.]]></description><link>https://www.i-kh.net/p/intro-to-project-management-for-developers-1</link><guid isPermaLink="false">https://www.i-kh.net/p/intro-to-project-management-for-developers-1</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Sun, 06 Sep 2026 12:29:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a software engineer, as you grow in seniority, at some point you may be asked to lead the delivery on a feature, an initiative, or a project of some sort. But what if you haven&#8217;t delivered a project yet? Or have tried to deliver a project or two and it didn&#8217;t go as well as you hoped?</p><p>In this series of posts, I&#8217;ll introduce a few informal project management techniques that should help you do better. These are based on my experience in the last 15-ish years of leading various software projects in four different companies on teams ranging from internal software to platform engineering to SaaS product teams.</p><p>The techniques will specifically address:</p><ul><li><p>Making sure that everyone is on the same page&#8212;including you.</p></li><li><p>Discovering dependencies, risks, and surprises early.</p></li><li><p>Producing a reasonable effort estimate.</p></li><li><p>Staying on top of delivery and having it go smoothly.</p></li><li><p>Having a smooth rollout.</p></li></ul><p>All of this won&#8217;t fit into one post, so I&#8217;ll break it up into three parts:</p><ul><li><p>Part 1 (this part): Initial notes and kicking off a project</p></li><li><p>Part 2: <a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-2">Technical design and planning</a></p></li><li><p>Part 2.5: <a href="https://www.i-kh.net/p/estimating-software-projects">Estimating software projects</a></p></li><li><p>Part 3: Staying on top of delivery (coming soon)</p></li></ul><p>But first&#8230;</p><h2>What&#8217;s a &#8220;project&#8221;?</h2><p>For the purpose of this post, it&#8217;s a chunk of work that:</p><ol><li><p>Has a clear &#8220;start&#8221; and &#8220;done&#8221;, like a new feature, an infrastructure upgrade, a refactor, or a minimum viable product for a new system; and</p></li><li><p>Has a delivery time between a single engineer working for a month on the low end and a team of 5-7 working for a couple quarters on the high end.</p></li></ol><p>Different organizations call this type of work by different names: epic, initiative, feature, or something else. For the purpose of this post, I&#8217;ll call it a &#8220;project&#8221;.</p><p>The overall principles from these posts would still be useful for work outside of this definition, though the specific techniques would be overkill for a week-long task and insufficient for a multi-year cross-department program.</p><p>Also, every company, team, and project is different, and what you&#8217;ll work on is not what I&#8217;ve worked on. So treat these posts less like rigid step-by-step instructions and more like a toolkit or a starting point for your own process.</p><p>With that in mind, let&#8217;s begin.</p><h2>You just got a new project. Now what?</h2><p>As a software engineer, your first instinct on a new project may be to start designing a solution or thinking through the code you&#8217;d write.</p><p>Suppress that instinct.</p><p>Instead, the first thing you&#8217;ll need to do is make sure that:</p><ol><li><p>It&#8217;s clear why the project is being done and what success looks like,</p></li><li><p>There are clear expectations for what exactly will be built, and</p></li><li><p>The right people agree on the direction.</p></li></ol><p>If you don&#8217;t do this, you might confidently deliver something that no one needs, and you&#8217;ll discover that only late into the project.</p><p>The rest of the post will focus on how to get those three things done. To do that, we&#8217;ll need to start one document and have a few meetings.</p><h2>Step 1: Start a project outline document</h2><p>To begin, we&#8217;ll need to document what we know about the project so far, and what kind of questions need to be answered. A great way to do that is to start a project outline document.</p><p>It can be a Word/Google doc, a page on the internal wiki (like Confluence), a PowerPoint deck, or any other document; the main criteria are that (1) it should be whatever your company uses for similar documents, and (2) bonus points if it can be easily shared and collaborated on.</p><p>In it, add several blank sections:</p><ul><li><p>Overview</p></li><li><p>What&#8217;s out of scope</p></li><li><p>Requirements (feel free to rename it to &#8220;Details&#8221; if you or your org are uncomfortable with the word &#8220;Requirements&#8221;)</p></li><li><p>Open Questions</p></li><li><p>Risks</p></li></ul><p>Don&#8217;t worry too much if you cannot complete&#8212;or even start&#8212;some of these sections until you&#8217;ve spoken to some stakeholders<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a>. But do try to fill out as much as you can eventually.</p><p>Here&#8217;s what goes into each section.</p><p><strong>&#8220;Overview&#8221; section</strong>: add a couple paragraphs with the project motivation for those who&#8217;re new to it, what goals it&#8217;s trying to accomplish, and what success looks like. It can also include a brief summary of what exactly would be built.</p><p><strong>&#8220;Out of scope&#8221; section:</strong> clearly state what the project will NOT deliver, or what may be delivered later but not this time around.</p><p><strong>&#8220;Requirements&#8221; section:</strong> this is usually the biggest section. In it, outline what you think the project is supposed to do, how it&#8217;s supposed to interact with any existing features/components/systems. For user-facing features this could also include outlines of user flows; for internal migrations or upgrades this could include the end-state vision and list of systems to upgrade. And so on.</p><p>You don&#8217;t need to include the fine details like the exact UI fields and validation error messages, but it should be clear enough that by the time you get to working on a detailed technical design, there are minimal surprises.</p><p>This is also a good time to look around and do a quick gut-check of whether the project is even possible by briefly taking a look at the code (probably with AI&#8217;s help these days), or reviewing the documentation for any external systems you&#8217;d be interfacing with (add a link to these in the doc). It&#8217;s also a good time to note which parts would be responsibilities of another team. Feel free to start sketching out the implementation too (see Part 2 for details), but don&#8217;t go too deep into it&#8212;we&#8217;re not at that stage yet, and a lot can still change.</p><p><strong>&#8220;Open questions&#8221; section:</strong> As you write out the requirements, you will inevitably run into spots where you&#8217;re not sure what exactly the expectations are. In those cases, stop and leave a bullet point in the &#8220;Open questions&#8221; section noting what should be clarified and who it should be clarified with. Alternatively, you can leave comments straight in the document, or you can add questions inline in a different color (<span data-color="#ff0000" style="color: rgb(255, 0, 0);">like this?</span>).</p><p><strong>&#8220;Risks&#8221; section:</strong> you can fill this out later during design/planning, but as you go it&#8217;s good to ask yourself what can go wrong. Usually it&#8217;s questions or concerns like &#8220;we probably can&#8217;t deliver X by the end of the quarter with only two people&#8221;, or &#8220;what if their API doesn&#8217;t support this?&#8221;, or &#8220;is team Y willing to deliver this by the end of the next month?&#8221;. Some of these can be answered by looking up the relevant info right away (e.g. the API question), but for others, you&#8217;ll need to follow up with the right people&#8212;more on that later.</p><h2>Step 2: Talk to the stakeholders</h2><p>Next, it&#8217;s time to book some meetings with people who can give you the necessary information. This can include the decision-makers like your managers or clients, subject matter experts in the relevant domains, or even developers on other teams who can explain how their systems work.</p><p>The main goals of these meetings will be to:</p><ol><li><p>Clarify what exactly needs to be delivered,</p></li><li><p>If you&#8217;ve written down anything in your project doc, confirm that it makes sense and is on the right track,</p></li><li><p>Answer any open questions you have, and</p></li><li><p>With the main decision-makers: establish the priorities, especially if some parts of the project cannot be delivered on time or will require more resources.</p></li></ol><p>I usually first meet with the people whose opinion matters the most, like my boss or the product manager or the client, and then work my way through everyone else.</p><p>You can also try to do this via chat or emails, but I find that at least at the start, it&#8217;s better to have a meeting because asynchronous communication doesn&#8217;t work as well until after the common expectations have been established.</p><p>Update the document as you learn new information and as the open questions and risks get addressed. Add the new risks and open questions as needed.</p><h4>Descoping and reprioritizing the work</h4><p>Sometimes it becomes clear that some things are bigger than originally thought or that they&#8217;re not realistically deliverable. These can become candidates for &#8220;descoping&#8221;: reducing the expectations or eliminating them entirely.</p><p>If you&#8217;re the full owner of the project with the power to make decisions on what gets done, then go ahead and cut or re-prioritize as needed&#8212;keeping in mind the project&#8217;s ultimate success criteria. Though depending on where things stand, you may need to have a chat with some stakeholders first to get their opinions or at least give a heads-up.</p><p>If someone else is the ultimate owner, I recommend against just saying &#8220;we cannot do this&#8221; or &#8220;we won&#8217;t do this&#8221;. Instead, I suggest stating the constraint and offering choices: &#8220;I don&#8217;t think we can realistically deliver both X and Y, which do you think should be a priority?&#8221;, or &#8220;there&#8217;s a high risk we cannot deliver X on time with two developers; do you think a third can be added? Or are we OK with X going into the next month/quarter/milestone/etc?&#8221; Then let them make the decision.</p><p>Anything that ends up being cut, moved, or deprioritized should be added to the &#8220;Out of scope&#8221; section in your project document together with any appropriate notes.</p><h4>Handling disagreements between major decision-makers</h4><p>Sometimes several important decision-makers disagree on key details or priorities.</p><p>In this case, the approach that worked best for me is to book a meeting titled something like &#8220;Agree on (topic of disagreement)&#8221; and invite all decision-makers&#8212;or, at least, the disagreeing ones&#8212;and let them discuss the issue and come to a conclusion. In my experience, they will almost always come to some sort of understanding. If they still disagree, the next steps are highly dependent on your circumstances; it can be anything from escalating the question to upper management to giving up on the project altogether.</p><h2>Last step: Final alignment</h2><p>Once most of the project details have been nailed down, it&#8217;s often useful to have one additional meeting with all the decision-makers and project participants where you&#8217;d go over the final outline of what will be done and what will not be done.</p><p>Depending on how your organization works, this can be either a dedicated meeting or it can be part of another meeting like bi-weekly refinement. Or you might even be able to do it asynchronously via email or chat. Though I do find it helpful to have everyone in the same room for this step.</p><h4>Keeping the project expectations up-to-date</h4><p>You now have a set of <em>initial</em> expectations for the project that everyone understands and agrees on. However, don&#8217;t be surprised if things change, especially if this is a larger project with a longer delivery time. When that happens, sometimes all key decision-makers will already be aware of it and in alignment, but sometimes they won&#8217;t. In that case, it&#8217;ll be your job to have any follow-up meetings or discussions to make sure that everyone is on the same page about the new project direction.</p><h2>Moving on</h2><p>Now that we&#8217;re clear on what&#8217;s to be done, we can move on to the next step: detailed design and planning.</p><ul><li><p>Next: <strong><a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-2">Intro to</a></strong><a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-2"> </a><strong><a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-2">project management for developers - Part 2: Technical design and planning</a></strong></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Interested in to get updates? Subscribe to be notified when I post.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>A &#8220;stakeholder&#8221; is basically anyone who can materially affect the project or will be materially affected by it. In practice, some stakeholders&#8217; opinions matter more than others, and some stakeholders are also decision-makers, but the terms aren't synonymous.</p></div></div>]]></content:encoded></item><item><title><![CDATA[AI agents aren’t people, so don’t bother lecturing them]]></title><description><![CDATA[As I browse around Reddit or Hackernews, I regularly see screenshots like this (link to post):]]></description><link>https://www.i-kh.net/p/ai-agents-are-not-people-and-you</link><guid isPermaLink="false">https://www.i-kh.net/p/ai-agents-are-not-people-and-you</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 31 Aug 2026 22:56:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ee15095b-e7aa-4849-9642-f8dae2e38434_1441x852.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As I browse around Reddit or Hackernews, I regularly see screenshots like this (<a href="https://www.reddit.com/r/ClaudeCode/comments/1w3lr2r/told_claude_dont_push_yet_let_me_test_it_first_it/">link to post</a>):</p><div class="captioned-image-container"><figure><div class="image-link image2" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jnq4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 424w, https://substackcdn.com/image/fetch/$s_!jnq4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 848w, https://substackcdn.com/image/fetch/$s_!jnq4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 1272w, https://substackcdn.com/image/fetch/$s_!jnq4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jnq4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png" width="461" height="180" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:180,&quot;width&quot;:461,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;r/ClaudeCode - told claude \&quot;dont push yet let me test it first\&quot;. it pushed anyway. asked who told it to push and it just... confessed&quot;,&quot;title&quot;:&quot;r/ClaudeCode - told claude \&quot;dont push yet let me test it first\&quot;. it pushed anyway. asked who told it to push and it just... confessed&quot;,&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="r/ClaudeCode - told claude &quot;dont push yet let me test it first&quot;. it pushed anyway. asked who told it to push and it just... confessed" title="r/ClaudeCode - told claude &quot;dont push yet let me test it first&quot;. it pushed anyway. asked who told it to push and it just... confessed" srcset="https://substackcdn.com/image/fetch/$s_!jnq4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 424w, https://substackcdn.com/image/fetch/$s_!jnq4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 848w, https://substackcdn.com/image/fetch/$s_!jnq4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 1272w, https://substackcdn.com/image/fetch/$s_!jnq4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8daeac31-fc15-40a2-afa7-4626dad67cbe_461x180.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></div></figure></div><p>Or this (<a href="https://www.reddit.com/r/ClaudeCode/comments/1w3sfki/opus_5_in_a_nutshell_adhd_plugin_enabled_model/">link to post</a>):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qcZ_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qcZ_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 424w, https://substackcdn.com/image/fetch/$s_!qcZ_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 848w, https://substackcdn.com/image/fetch/$s_!qcZ_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 1272w, https://substackcdn.com/image/fetch/$s_!qcZ_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qcZ_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png" width="640" height="771" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:771,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;r/ClaudeCode - Opus 5 in a nutshell (ADHD plugin enabled, model still verbose and says 'I've been ignoring the plugin')&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="r/ClaudeCode - Opus 5 in a nutshell (ADHD plugin enabled, model still verbose and says 'I've been ignoring the plugin')" title="r/ClaudeCode - Opus 5 in a nutshell (ADHD plugin enabled, model still verbose and says 'I've been ignoring the plugin')" srcset="https://substackcdn.com/image/fetch/$s_!qcZ_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 424w, https://substackcdn.com/image/fetch/$s_!qcZ_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 848w, https://substackcdn.com/image/fetch/$s_!qcZ_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.png 1272w, https://substackcdn.com/image/fetch/$s_!qcZ_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F799e51a5-2e66-4543-935c-ceb81513ca85_640x771.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I understand why people have vent at Claude/Cursor/whatever when it screws up. It talks like a person, so when it messes up, it&#8217;s tempting to tell it off, maybe even add a swear word or two. </p><p>However, I think not a helpful approach. Instead, when that happens, pause for a sec, and consider this:</p><ul><li><p>The agent is going to forget the conversation once the session ends. Well, unless it has memory of some sort, in which case it might remember the wrong lesson.</p></li><li><p>What do you want the outcome of the conversation to be? Will yelling at the agent solve your problem? Will it prevent the mistake from happening again?</p></li><li><p>The agent is not a human. It&#8217;s a program that just demonstrated a bug. And you&#8217;re a software engineer. Why don&#8217;t you do some debugging?</p></li></ul><p>So rather than typing &#8220;what the fuck did you just do??&#8221;, try some version of this prompt:</p><blockquote><p>It looks like after the last prompt, {describe the issue}. Investigate why this happened and try to find the root cause. Suggest approaches to avoid it in the future.</p></blockquote><p>Or just step back and think through how the issue could have happened&#8212;based on what you know about LLMs so far. Could it have been context rot from too many instructions? Or was important context not added somewhere? Should you have used a smarter model or set the reasoning level higher? Or maybe you need to update the rules in <code>AGENTS.md</code>/<code>CLAUDE.md</code>?</p><p>In the last year, I&#8217;ve now run twice into a situation where I was seriously tempted to type &#8220;WTF???&#8221; as my next prompt. However, after doing some investigating, the first issue led me to change the way I prompt and write skills, and the second issue turned out to be <a href="https://github.com/microsoft/vscode/issues/318131">a bug</a>.</p><p>Finally, keep in mind that LLMs are non-deterministic systems, and there&#8217;s an inherent risk that sometimes they&#8217;ll do something random and stupid. So it&#8217;s a good idea to put some boundaries in place to prevent them from causing real damage, such as blocking force-push on the repo&#8217;s main branch, or blocking write access to the prod infrastructure.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Like what you&#8217;ve read? Subscribe for more:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[My Spec-First Workflow for AI Coding Agents]]></title><description><![CDATA[If you&#8217;ve used AI agents enough, you may have noticed that for really simple tasks you can just prompt them, and for more complex tasks you may want to generate a plan first.]]></description><link>https://www.i-kh.net/p/my-spec-first-workflow-for-ai-coding</link><guid isPermaLink="false">https://www.i-kh.net/p/my-spec-first-workflow-for-ai-coding</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Fri, 28 Aug 2026 21:43:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you&#8217;ve used AI agents enough, you may have noticed that for really simple tasks you can just prompt them, and for more complex tasks you may want to generate a plan first. </p><p>And if you want the agent to code a complex feature end-to-end, you may want to add another step before planning: a requirements and design document, also called a &#8220;spec&#8221; file.</p><p>For me, once I&#8217;ve dialed in the technique, these spec files have been responsible for the single biggest productivity bump I&#8217;ve ever had. Looking back at the features and projects I&#8217;ve delivered since I started using them, when I compare the old estimates with the actual delivery times, it&#8217;s safe to say that my productivity rose around 2x while <em>improving</em> the quality&#8212;as observed by the number of bugs found by our manual QA and the number of post-deployment fixes (more on that <a href="https://www.i-kh.net/p/if-ai-coding-is-lowering-your-code">here</a>).</p><p>But how exactly should you write these spec files to get the most out of them? I&#8217;m sure many people have arrived at their own approaches, many of them better than mine, but here&#8217;s how I do it.</p><p>Note that I use Cursor (at work) and VS Code+Copilot (at home), but in theory this process is very harness-agnostic and should work with most agents.</p><h2>Step 0: the template</h2><p>The first thing I do is copy+paste the template below into the working folder and fill out the obvious parts: the title, the overview sentence, and a rough sketch of the initial requirements. (By the way, if the template looks suspiciously like a miniature version of <a href="https://www.i-kh.net/p/intro-to-project-management-for-developers-1">my method for planning larger projects</a>, that&#8217;s not a coincidence).</p><p>Note a few blocks of text that are intended strictly for the agents that will be updating this file:</p><ul><li><p>Document rules: deals with a variety of annoying quirks of various models. </p></li><li><p>High-level design: contains a sentence telling the agent to keep the designs high-level.</p></li><li><p>Open Questions section: contains rules for updating the open questions.</p></li></ul><p>The rest are the instructions and examples for you, the human driving the AI. </p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown"># Title - short description of the project

A statement in a sentence or two describing what you'd like to do.
Example: we'd like to add the ability to send email notifications in our system.

## Document rules

Do not delete this instruction paragraph. Follow it carefully when editing 
this document. This file should contain final designs only; do not track 
changes or discuss pros/cons of alternatives, or discuss previous 
implementation plans unless explicitly prompted. Avoid leaving large 
paragraph of text, they're hard to read; find another way to organize 
text if necessary. Do not use headings past h3 (`###`), find another way 
to organize text if needed. Keep changes brief and to the point - avoid 
adding any text that doesn't need to be added. Avoid large blocks of code, 
though feel free to add focused blocks of code if it really helps 
communicate the design. 

All target designs/future designs should use either future tense ("X will 
use...") or describe the change to be made ("Update X to..."); present 
tense ("X runs only on...") should be used only when describing the 
currently implemented designs. Using present sense for future target 
states may confuse the reader.

## Requirements

Outline the requirements. Feel free to break them up into subsections 
if needed, or can just start in point form and expand later.

Example: 

We'll want to send emails on:
- Account creation
- Account deletion
- Manager-initiated account activation
- Manager-initiated account deactivation

New accounts are created through self-serve signup only, and account-creation 
emails are sent for those self-serve signups.

For account deletion, send the email for both self-serve deletions and 
manager-initiated deletions.

... And so on.

## High-level design

To be filled out later.

This section should contain high-level designs only. Avoid detailed designs, 
that's for the planning/implementation agent later.

## Open questions

- **Example open question**: Example open question details.

Do not remove this section or this instruction paragraph. If 
you're removing the last open question, add a correctly formatted 
example placeholder question so that future agent runs can add 
more open questions if they need to. The placeholder should 
be: `**Example open question**: Example open question details.`
</code></pre></div><p>By the way, feel free to add or change any sections as needed. For example, when refactoring, I like to add another section called &#8220;Current design&#8221; and rename &#8220;High-level design&#8221; to &#8220;Target design&#8221;.</p><h2>Step 1: Requirements</h2><p>Now is a good time to pause and think through the requirements a bit more, filling them out as much as you can.</p><p>Here are some of the things I do next:</p><ul><li><p>Talk to my product manager, the designer, or any other relevant people to refine the edge cases and clarify specific behaviors.</p></li><li><p>Get mock-ups from the designer, take the screenshots, give those screenshots to my coding agent, and ask the agent to (1) describe what it sees, and (2) add those details to the requirements section. (I usually ask it to describe the changes in terms of any existing components in the codebase as much as possible.)</p></li><li><p>Grab any third-party docs I need and either reference them in the spec file, or get the agent to summarize them.</p></li><li><p>Ask the coding agent to review the requirements for any inconsistencies or gaps. </p></li></ul><p>For the last point, there&#8217;s a specific prompt that I like to use:</p><blockquote><p>We&#8217;re working on `my-spec-file.md`. Do the following:</p><p>* Review the file and any relevant documents and code. Think through how you&#8217;d implement it. Are there any gaps in the requirements? Any conflicts? Other concerns? Any unexpected interactions with existing functionality? Emit a list of issues. We&#8217;re looking only at the issues with the requirements at the moment, not technical design.</p><p>* Review each issue from the previous step. For every one that is actually a non-issue, ignore it. For any issue that has a single obvious best answer or any that can be answered with &#8220;just do what the code does now&#8221;, update `my-spec-file.md` to reflect that. For all others, add them to the &#8220;Open questions&#8221; section.</p></blockquote><p>In a system of any complexity, this will almost always find something to add to the document. And a smarter model (like say, Anthropic&#8217;s Sonnet/Opus, or OpenAI&#8217;s Terra/Sol) may also raise some open questions that I haven&#8217;t thought of.</p><p>Though sometimes they raise dumb questions too, or make wrong edits.</p><h2>Step 2: Carefully review the updated requirements</h2><p>If you usually skip reviewing AI&#8217;s output, I won&#8217;t judge you much (I&#8217;ve done that at times), but this is really not the time to do it. At the requirements stage, a wrong assumption by AI will take 2 min to detect and fix. If it&#8217;s missed, it could cost you 30 min of rework at best or become a production incident at worst.</p><p>Think about it like this: you&#8217;re ultimately responsible for these requirements. The AI can help you, but it just cannot know as much about the requirements as you or the humans around you.</p><p>I usually do a couple of cycles of prompt for gaps/open questions &#8594; review &#8594; apply fixes/answer questions &#8594; prompt for gaps again.</p><h2>Step 3: High-level design</h2><p>Once the requirements have stabilized, it&#8217;s time to move on to the design.</p><p>On simpler features you can just directly prompt for one, but more often than not I do something like this:</p><ul><li><p>First, I put down a few technical decisions that I know upfront: e.g. use a specific library, or a specific third-party service, or that service X should own objects Y. This is also a good time to add sizing constraints: should scale to at least 2 million of {whatever object} across N users, should have p95 latency &lt;500ms, and so on.</p></li><li><p>Second, I usually have a few open questions of my own, like how to design a certain part, or whether a certain thing is even possible. </p></li><li><p>Then, I systematically work through various parts using the <code>/tech-design</code> skill below:</p></li></ul><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">---
name: tech-design
description: 'Come up with a technical design for a problem. Use when asked a challenging technical question or to design a solution for one specific problem. Researches best practices, generates options, evaluates tradeoffs, and recommends the best approach. Best for one focused problem &#8212; invoke separately for each independent decision.'
---

# Come up with a technical design for a problem

Considers and selects a technical design for one problem. 
Best for one specific problem, not when there are multiple 
independent decisions to be made. If there are multiple 
independent decisions, it's best to use this skill for each decision.

## When to use

- Use this skill for answering a challenging technical question 
  or coming up with a technical design for one specific problem.
- Avoid using this to solve multiple problems at once. If there 
  are multiple independent problems/questions, it's best to invoke 
  this skill for each question/problem separately.

## Instructions

- Read the relevant documentation.
- If there are AGENTS.md, CLAUDE.md, cursor rules, or any other rules 
  files, review those.
- If there is code to review, review the relevant code.
- Research online to see what other people have done, what the best 
  practices are, any insights from blogs, research papers, or people 
  who've done similar things before.
- Think through the problem.
- Come up with the parameters to evaluate the solution on. Examples 
  could be feasibility, implementation cost, dollar cost, architectural 
  fit, simplicity/understandability, security, performance, and others. 
  Don't just take this list, come up with an appropriate list yourself.
- Come up with some design options.
- Consider pros/cons of each design option, tradeoffs, gotchas, and 
  evaluate it against each of the previously selected evaluation 
  parameters. Critique each solution.
- Try to improve each design option based on the critique.
- Do a final review/ranking/evaluation of the design options and select 
  the best one.
- Output the candidates, the decision criteria, the evaluation of each 
  candidate against the criteria, and the final recommendation.

Do not make any changes unless explicitly prompted; just output your findings in chat.
</code></pre></div><p>The prompt might look something like this:</p><blockquote><p>/tech-design a solution to this open question from my-spec.md:</p><p>&gt;Question details&#8230;</p></blockquote><p>Or this:</p><blockquote><p>/tech-design the best approach to implement (whatever thing)</p><p>You can find additional context in (list of files)</p></blockquote><p>Note that this skill doesn&#8217;t mention anything about modifying the spec document; in fact, it explicitly asks not to make changes. This is because I prefer to review the decision and, if I&#8217;m not happy with the result, re-prompt with additional information or ask follow-up questions and refine the design.</p><p>When I&#8217;m happy with the result, I explicitly ask:</p><blockquote><p>Update my-spec-file.md to reflect the recommended approach.</p></blockquote><h2>Step 4: Review the designs</h2><p>Aside from the usual human review, I also like to run this variant of the review prompt a couple times before settling on the design:</p><blockquote><p>We&#8217;re about to start implementing my-spec-file.md. Before doing that, I&#8217;d like to do a review of the technical design. Do the following:</p><p>* Review the file and any relevant documents and code. Think through how you&#8217;d implement it, in detail. Do you have any concerns? Are there any gaps in the requirements or design? Any conflicts? Any remaining significant decisions to be made? Any unexpected interactions with existing functionality? Emit a list of issues.</p><p>* Review each issue from the previous step. For every one that is actually a non-issue, ignore it. For any issue that has a single obvious best answer or any that can be answered with &#8220;just do what the code does now&#8221;, update my-spec-file.md to reflect that. For all others, add them to the &#8220;Open questions&#8221; section.</p></blockquote><p>This usually produces a number of edits and follow-up questions, which I review, correct, and answer. Sometimes I can answer the open questions immediately, and sometimes I invoke the /tech-design skill to answer them.</p><p>Sometimes these reviews reveal new missed requirements or unexpected interactions that force me to step back and rethink the approach.</p><p>I usually do a couple of these review passes before moving on to the next step.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.i-kh.net/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">Like what you&#8217;re reading? Subscribe for more</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2>Step 5: Phasing</h2><p>At this point, the design is largely complete and now we&#8217;re moving on to the implementation.</p><p>For simpler features, we can, again, just tell the agent to plan and implement. However, for larger features I find it useful to break up the work into implementation phases.</p><p>This can take a few shapes:</p><ul><li><p>For features spanning multiple repos, I can ask the agent to figure out which PRs should be created in what order. Some models can be overzealous in splitting the PRs, so I might ask to bundle the changes in as few PRs as practically possible.</p></li><li><p>For a large implementation in a single repo, I ask to break up the changes into phases containing maybe 2,000-5,000 lines of code each. This (1) helps me break down the changes into reviewable chunks, and (2) lets me catch issues early so that I don&#8217;t have to fix the whole 30,000 LOC changeset.</p></li></ul><h2>That&#8217;s about it</h2><p>From here, I&#8217;m mostly in cruise-control mode: prompt to plan, prompt to implement, review, apply fixes, prompt to plan the next phase, etc.</p><p>I have other skills for generating plans the way I like, implementing the changes, reviewing the emitted code, and making PRs, but they&#8217;re outside the scope of this post.</p><p>I&#8217;m curious: what is everyone else doing? How are you handling requirements, design or planning?</p>]]></content:encoded></item><item><title><![CDATA[Canadian housing crisis: what will it take to fix it?]]></title><description><![CDATA[What exactly is the scale of the housing crisis in Canada?]]></description><link>https://www.i-kh.net/p/housing-crisis-what-will-it-take-to-fix</link><guid isPermaLink="false">https://www.i-kh.net/p/housing-crisis-what-will-it-take-to-fix</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Sun, 08 Sep 2024 21:09:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4pe1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What exactly is the scale of the housing crisis in Canada? Fortunately, most of the data is pretty straightforward to find. You can go to the Statistics Canada website, grab the <a href="https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=3610068801">housing stock table</a> and the <a href="https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=1710000501">population by age table</a> (click &#8220;Add/remove data&#8221; to see more years), and pretty quickly arrive at something like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;963c62b3-e6f4-4e8c-9e80-bd1e2dfd46ec&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">                                  2016          2024
Population &gt; 18               29,027,447    32,600,713
Units available               15,507,364    16,786,020
Units/person                       0.534         0.515
Units needed to get to
2016 levels                           -       630,000</code></pre></div><p>I.e. we need <strong>630,000</strong> houses or apartments just to get back to 2016 levels of housing availability. A bit over half of this number comes from Ontario; repeating the math for that province gives us a shortage of 333,000 units compared to 2016.</p><p>To be clear, this number misses a lot of nuances: we don&#8217;t know which of these &#8220;units&#8221; are 8-bedroom houses and which are micro-condos, and we don&#8217;t know which of these adults are single and which have families.</p><p>On the surface, this shortage of 630,000 units doesn&#8217;t seem too horrifying: in 2023, the construction industry has started building 240,267 new units (<a href="https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=3410013501">CMHC housing starts table</a>) &#8212; down from the peak of 271,198 in 2021 &#8212; so it might look like it should take a bit less than three years to catch up.</p><p>But remember: Canada is a growing country, so as we&#8217;re building these housing units, new people over 18 are appearing. So let&#8217;s update our math. Suppose Canada&#8217;s growth follows StatCan&#8217;s moderate growth projections (M2 scenario <a href="https://www150.statcan.gc.ca/t1/tbl1/en/tv.action?pid=1710005701">in this table</a>), and we continue building houses at the same rate as we did in 2021 (the best year we&#8217;ve seen so far). How long will it take to catch up to the 2016 housing level?</p><p>Well, then the projection looks something like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;7c939164-0f1d-4a1e-939a-7a82372a2498&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Year    Population &gt; 18    Units short
2025        33,283,800         577,130
2026        33,548,800         495,079
2027        33,822,800         418,454
2028        34,312,900         457,893
2029        34,800,100         496,398
2030        35,280,800         532,044
2031        35,761,400         568,248
2032        36,241,000         604,527
2033        36,715,500         638,690
2034        37,187,400         672,071
2035        37,652,100         702,210</code></pre></div><p>Uh-oh, we never catch up.</p><h2>So what will it take?</h2><p>I&#8217;ll spare you the math and go straight to the answer: if we want to get back to 2016 housing stock levels by 2035, then over the next five years we need to increase the housing starts by <strong>26%</strong> over the 2021 levels to about 380,000 starts/year, with the bulk of this increase happening in Ontario, which needs to raise its housing starts by ~45%.</p><p>It&#8217;s not a small amount, but not impossible either. For comparison, in the years between 2016 and 2021, housing starts have increased 37% Canada-wide ans 33% in Ontario.</p><h2>But there are a few problems in the way</h2><p>A lot of the discourse online and among activists has been focused on <a href="https://www.cmhc-schl.gc.ca/blog/2023/approval-delays-linked-lower-housing-affordability">onerous regulations</a>, <a href="https://www.youtube.com/watch?v=Xy5xnYLWffE">slow approvals</a>, and <a href="https://www.youtube.com/watch?v=ozwkP9Zsi0Y&amp;t=519s">unhelpful building codes</a> &#8212; and rightfully so. That said, these seem to be improving as the public mood shifts towards building more housing, and, looking at the industry reports, it seems like at <a href="https://www.altusgroup.com/insights/cost-escalation-in-new-construction-a-2024-update/?utm_source=google&amp;utm_medium=organic">least some of the insiders</a> no longer see the public policy as the biggest long-term drag on construction.</p><p>There are a couple of other major problems though.</p><p>First, we need the new housing starts to go up, but instead since 2021, they&#8217;ve been going down. The explanation for this is fairly straightforward: less money has been spent on building new houses because the interest rates have gone up and house purchases have slowed down.</p><p>This problem will partly fix itself as the Bank of Canada <a href="https://www.canadianmortgagetrends.com/2024/07/will-the-bank-of-canada-deliver-another-175-bps-in-rate-cuts-td-and-cibc-say-yes/">lowers its policy interest rate</a>. However, it won&#8217;t cut the rate back down to 0.25%, and the total investment into new housing isn&#8217;t projected to go back up to the 2021 levels either (source: <a href="https://www.buildforce.ca/system/files/forecast_summary_reports/2024%20Canada%20Const%20%26amp%3B%20Maint%20Looking%20Forward.pdf?language=en">BuildForce National Summary for 2024</a>):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4pe1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4pe1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 424w, https://substackcdn.com/image/fetch/$s_!4pe1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 848w, https://substackcdn.com/image/fetch/$s_!4pe1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 1272w, https://substackcdn.com/image/fetch/$s_!4pe1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4pe1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png" width="867" height="409" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7005a585-eacf-441a-a17e-737486c45aca_867x409.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:409,&quot;width&quot;:867,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!4pe1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 424w, https://substackcdn.com/image/fetch/$s_!4pe1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 848w, https://substackcdn.com/image/fetch/$s_!4pe1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.png 1272w, https://substackcdn.com/image/fetch/$s_!4pe1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7005a585-eacf-441a-a17e-737486c45aca_867x409.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>But we need the investment to go much higher: if the average historic costs per housing unit stay the same, we&#8217;ll need to be investing as much as $54 billion per year more than we&#8217;re forecast to catch up to our 2016 housing availability target. If that money doesn&#8217;t materialize from somewhere, no amount of regulation reform will help plug the gap.</p><p>The second problem is the shortage of skilled labor in the construction industry, which is projected to worsen due to retirement. In the short-term, construction is limited by lack of people with a few specific skill sets like crane operators, elevator mechanics, or ironworkers, especially in major cities like Toronto (source: <a href="https://www.buildforce.ca/system/files/forecast_summary_reports/2024%20ON%20Constr%20Maint%20Looking%20Forward.pdf?language=en">BuildForce Ontario report 2024</a>):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7tKH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7tKH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 424w, https://substackcdn.com/image/fetch/$s_!7tKH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 848w, https://substackcdn.com/image/fetch/$s_!7tKH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 1272w, https://substackcdn.com/image/fetch/$s_!7tKH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7tKH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png" width="733" height="429" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:429,&quot;width&quot;:733,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!7tKH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 424w, https://substackcdn.com/image/fetch/$s_!7tKH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 848w, https://substackcdn.com/image/fetch/$s_!7tKH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.png 1272w, https://substackcdn.com/image/fetch/$s_!7tKH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F605244c5-aea5-4eb9-b9de-c5f7c157d365_733x429.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HdK-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HdK-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 424w, https://substackcdn.com/image/fetch/$s_!HdK-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 848w, https://substackcdn.com/image/fetch/$s_!HdK-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 1272w, https://substackcdn.com/image/fetch/$s_!HdK-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HdK-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png" width="729" height="396" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:396,&quot;width&quot;:729,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!HdK-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 424w, https://substackcdn.com/image/fetch/$s_!HdK-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 848w, https://substackcdn.com/image/fetch/$s_!HdK-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.png 1272w, https://substackcdn.com/image/fetch/$s_!HdK-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3720a1f-6137-4676-ba1a-7c9bd7b0aadd_729x396.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the long-term, from the same report, based on the current hiring levels and trades education pipeline, Ontario alone is expected to be short 35,500 construction workers by 2033 &#8212; and that&#8217;s assuming BuildForce&#8217;s own not-quite-adequate construction investment forecast seen in the earlier graph. To get back to 2016 affordability levels in a reasonable time, we&#8217;d need to find more skilled construction workers somewhere, either by attracting more young people to trades locally, or through immigration.</p><h2>Or&#8230; what if we lower the population growth?</h2><p>While we work on addressing the supply-side issues of housing, there&#8217;s one lever in the hands of the federal government that can easily control the demand side: immigration levels.</p><p>How will the changes to the immigration policy affect the outcomes?</p><p>Let&#8217;s tweak some numbers and redo the math:</p><ul><li><p>StatCan&#8217;s M2 growth projection scenario already assumes a net departure of around 212k non-permanent residents per year between 2025 and 2027. That&#8217;s roughly consistent with reducing foreign students to about 2019 numbers and losing about half of the temporary foreign worker permit holders. Let&#8217;s keep this as-is.</p></li><li><p>The current permanent resident admission target is 500k/year. Let&#8217;s lower it to 350k until 2035, which will still keep it mostly above the <a href="https://en.wikipedia.org/wiki/Canada_immigration_statistics">historic levels</a> and at around 0.8% of the current population.</p></li></ul><p>Let&#8217;s keep the construction industry output at their 2021 levels and see what the situation looks like:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;4c1e7291-a306-4514-b037-f05a07fb1232&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Year    Population &gt; 18    Units short
2025        33,283,800         668,723
2026        33,548,800         521,036
2027        33,822,800         382,890
2028        34,312,900         250,171
2029        34,800,100         233,516
2030        35,280,800         215,927
2031        35,761,400         195,478
2032        36,241,000         175,588
2033        36,715,500         155,773
2034        37,187,400         111,129
2035        37,652,100          85,173</code></pre></div><p>We gradually catch up! Not quickly, but the effects should start being felt after the first year, and should improve every year after that. And if the construction industry raises its output by just 3%/year (for a total of 12% in 5 years), we get to 2016 housing availability levels by 2031.</p><h2>Conclusions</h2><p>It took a while to get into the current housing crisis, and it will likely take a while to get out. Whoever ends up taking on this will have their work cut out for them.</p><p>We&#8217;ll need:</p><ul><li><p>The federal government doing its part in controlling the demand by managing the immigration levels.</p></li><li><p>Cities and provinces, especially Ontario and BC, to keep pushing for regulatory reforms;</p></li><li><p>Provinces continuing to expand capacity for trades education and making it more attractive for young people;</p></li><li><p>The construction industry finding ways to build better houses and apartments for less;</p></li><li><p>Figure out how to keep funding flowing into the construction industry;</p></li></ul><p>Whatever happens, I will keep following this with great interest.</p>]]></content:encoded></item><item><title><![CDATA[My lazy Wordle strategy: same words every time]]></title><description><![CDATA[TL;DR: After the analysis in this post, I started using SLANT/PRICE/DOUGH/BALMY, but it may not be the best sequence for you.]]></description><link>https://www.i-kh.net/p/my-lazy-wordle-strategy</link><guid isPermaLink="false">https://www.i-kh.net/p/my-lazy-wordle-strategy</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Fri, 22 Apr 2022 19:21:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!wkQp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are lots of great videos and articles on the optimal <a href="https://en.wikipedia.org/wiki/Wordle">Wordle</a> strategy. I particularly enjoyed <a href="https://www.youtube.com/watch?v=v68zYyaEmEA">this YouTube video</a> by 3Blue1Brown on using the information theory to come up with the best guesses.</p><p>But I can&#8217;t play like that. First, I&#8217;m lazy, and second, my slow human brain can&#8217;t do information theory calculations or depth-first searches.</p><p>Instead, every time I play Wordle, I enter the same sequence of words until it feels like there aren&#8217;t many solutions left, at which point I try to make more tailored guesses.</p><p>Here are a couple examples of my recent games:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0xXn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0xXn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 424w, https://substackcdn.com/image/fetch/$s_!0xXn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 848w, https://substackcdn.com/image/fetch/$s_!0xXn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 1272w, https://substackcdn.com/image/fetch/$s_!0xXn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0xXn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png" width="350" height="288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:288,&quot;width&quot;:350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0xXn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 424w, https://substackcdn.com/image/fetch/$s_!0xXn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 848w, https://substackcdn.com/image/fetch/$s_!0xXn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 1272w, https://substackcdn.com/image/fetch/$s_!0xXn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30e3ba99-6a0d-422a-9c39-9300657b3151_350x288.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wkQp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wkQp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 424w, https://substackcdn.com/image/fetch/$s_!wkQp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 848w, https://substackcdn.com/image/fetch/$s_!wkQp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 1272w, https://substackcdn.com/image/fetch/$s_!wkQp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wkQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png" width="340" height="343" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:343,&quot;width&quot;:340,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wkQp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 424w, https://substackcdn.com/image/fetch/$s_!wkQp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 848w, https://substackcdn.com/image/fetch/$s_!wkQp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.png 1272w, https://substackcdn.com/image/fetch/$s_!wkQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba9e4c5b-a807-43e7-bf0b-f40f115853ee_340x343.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Until today, my go-to words were <code>STALE</code>, <code>CHIRP</code>, <code>MOUND</code>, and <code>GAWKY</code>, picked mostly by gut feel while trying to check as many frequently used letters as possible. So far I&#8217;ve been doing alright with them.</p><h2>But can we do better?</h2><p>Yes! Let&#8217;s use math and programming to do better.</p><p>Though to do computer science, we&#8217;ll need a more precise algorithm than &#8220;play these words until it feels like there aren&#8217;t many solutions left&#8221;. Let&#8217;s go with this:</p><ol><li><p>Pick four words.</p></li><li><p>In every game, keep guessing these words in order.</p></li><li><p>If there are 3 or fewer possible solutions left, make tailored guesses that minimize the number of turns to victory.</p></li></ol><p>Oh, and let&#8217;s use only the list of 2309 valid solution words (heplfully provided in Wordle&#8217;s JavaScript source code), and ignore the larger list of valid guesses. In part, that&#8217;s to make the calculations simpler, and in part because you&#8217;ll forget that <code>THEWY</code> is an acceptable guess by the time you&#8217;ll finish reading this sentence.</p><h2>Pick words that produce fewest remaining possible solutions?</h2><p>That was the first thing I tried.</p><p>For the first word, I picked one that resulted in the lowest remaining <a href="https://en.wikipedia.org/wiki/Entropy_(information_theory)">information entropy</a> (basically, fewest remaining options) on average across any of the 2309 valid solutions. That turned out to be <code>RAISE</code>.</p><p>Then, I picked the next word that gave me (on average, across all solutions) the most information after guessing <code>RAISE</code>. That turned out to be <code>CLOTH</code>. And so on, getting <code>DUMPY</code> and <code>BEGAN</code> as the best third and fourth words.</p><p>But how does it compare to the original <code>STALE</code>&gt;<code>CHIRP</code>&gt;<code>MOUND</code>&gt;<code>GAWKY</code>? If we simulate all 2309 possible games we see that:</p><ul><li><p><code>RAISE</code>/<code>CLOTH</code>/<code>DUMPY</code>/<code>BEGAN</code> wins all games and uses 3.89 guesses on average.</p></li><li><p>My original <code>STALE</code>/<code>CHIRP</code>/<code>MOUND</code>/<code>GAWKY</code> wins all games and uses 3.84 (!) guesses on average.</p></li></ul><p>&#128562; &#8265;&#65039; My original gut-feel word choices did better?</p><h2>Because each word being optimal &#8800; the full set is optimal</h2><p>So it turns out it&#8217;s not enough to optimize each word; instead, we have to jointly optimize the entire sequence <code>WORD1</code> <code>WORD2</code> <code>WORD3</code> <code>WORD4</code> across all possible word sequences.</p><p>But that&#8217;s a lot of sequences! I&#8217;m not sure how much exactly 2309<sup>4</sup> is, but it&#8217;s definitely more than my computer can handle. Even doing some intelligent pruning (e.g. &#8216;a letter must not repeat in the first 3 words&#8217;) still leaves a lot of options to evaluate. What else can we do to cut it down?</p><p>What I ended up doing was ranking all words by the number of bits of information that they provide, picking the top 10-100 words at each position for a total of ~160,000 four-word combinations, and then simulating all possible games for each sequence.</p><p>After two days at 100% CPU, my computer gave me the answer:</p><ul><li><p><code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code>: 3.79991 average guesses to win.</p></li></ul><p>But there were a lot of other sequences that produced similar results. For example #2 sequence was <code>CRANE</code> <code>SPILT</code> <code>DOUGH</code> <code>BALMY</code> that took on average 3.8008 guesses to win.</p><h2>But what if I&#8217;m a smart and tailor my guesses sooner?</h2><p>Or, to be less flippant, you can often get into situations where there are more than three guesses left, but you can easily enumerate them. The simplest example is if your first guess <code>SHARE</code> results in something like </p><p>There are lots of great videos and articles on the optimal <a href="https://en.wikipedia.org/wiki/Wordle">Wordle</a> strategy. I particularly enjoyed <a href="https://www.youtube.com/watch?v=v68zYyaEmEA">this YouTube video</a> by 3Blue1Brown on using the information theory to come up with the best guesses.</p><p>But I can&#8217;t play like that. First, I&#8217;m lazy, and second, my slow human brain can&#8217;t do information theory calculations or depth-first searches.</p><p>Instead, every time I play Wordle, I enter the same sequence of words until it feels like there aren&#8217;t many solutions left, at which point I try to make more tailored guesses.</p><p>Here are a couple examples of my recent games:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xWZ1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xWZ1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 424w, https://substackcdn.com/image/fetch/$s_!xWZ1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 848w, https://substackcdn.com/image/fetch/$s_!xWZ1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 1272w, https://substackcdn.com/image/fetch/$s_!xWZ1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xWZ1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png" width="350" height="288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:288,&quot;width&quot;:350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xWZ1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 424w, https://substackcdn.com/image/fetch/$s_!xWZ1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 848w, https://substackcdn.com/image/fetch/$s_!xWZ1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.png 1272w, https://substackcdn.com/image/fetch/$s_!xWZ1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf4f992c-3299-485e-b9e5-200a1778b40c_350x288.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UCj3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UCj3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 424w, https://substackcdn.com/image/fetch/$s_!UCj3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 848w, https://substackcdn.com/image/fetch/$s_!UCj3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 1272w, https://substackcdn.com/image/fetch/$s_!UCj3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UCj3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png" width="340" height="343" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:343,&quot;width&quot;:340,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UCj3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 424w, https://substackcdn.com/image/fetch/$s_!UCj3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 848w, https://substackcdn.com/image/fetch/$s_!UCj3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.png 1272w, https://substackcdn.com/image/fetch/$s_!UCj3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eaeb361-3bb8-4f15-9846-ebffab573077_340x343.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Until today, my go-to words were <code>STALE</code>, <code>CHIRP</code>, <code>MOUND</code>, and <code>GAWKY</code>, picked mostly by gut feel while trying to check as many frequently used letters as possible. So far I&#8217;ve been doing alright with them.</p><h2>But can we do better?</h2><p>Yes! Let&#8217;s use math and programming to do better.</p><p>Though to do computer science, we&#8217;ll need a more precise algorithm than &#8220;play these words until it feels like there aren&#8217;t many solutions left&#8221;. Let&#8217;s go with this:</p><ol><li><p>Pick four words.</p></li><li><p>In every game, keep guessing these words in order.</p></li><li><p>If there are 3 or fewer possible solutions left, make tailored guesses that minimize the number of turns to victory.</p></li></ol><p>Oh, and let&#8217;s use only the list of 2309 valid solution words (heplfully provided in Wordle&#8217;s JavaScript source code), and ignore the larger list of valid guesses. In part, that&#8217;s to make the calculations simpler, and in part because you&#8217;ll forget that <code>THEWY</code> is an acceptable guess by the time you&#8217;ll finish reading this sentence.</p><h2>Pick words that produce fewest remaining possible solutions?</h2><p>That was the first thing I tried.</p><p>For the first word, I picked one that resulted in the lowest remaining <a href="https://en.wikipedia.org/wiki/Entropy_(information_theory)">information entropy</a> (basically, fewest remaining options) on average across any of the 2309 valid solutions. That turned out to be <code>RAISE</code>.</p><p>Then, I picked the next word that gave me (on average, across all solutions) the most information after guessing <code>RAISE</code>. That turned out to be <code>CLOTH</code>. And so on, getting <code>DUMPY</code> and <code>BEGAN</code> as the best third and fourth words.</p><p>(Along the way, I had to keep in mind that I had to switch to &#8220;smart&#8221; guesses if I had 3 or fewer valid solutions left.)</p><p>Here&#8217;s what each word contributed:</p><p>Guess Ave. remaining entropy (bits) Ave. options remaining Worst case options remaining <code>RAISE</code> 5.2 17.5 167 <code>CLOTH</code> 1.8 2.38 30 <code>DUMPY</code> 0.8 1.53 6 <code>BEGAN</code> 0.4 1.28 4</p><p>But how does it compare to the original <code>STALE</code>&gt;<code>CHIRP</code>&gt;<code>MOUND</code>&gt;<code>GAWKY</code>? If we simulate all 2309 possible games we see that:</p><ul><li><p><code>RAISE</code> <code>CLOTH</code> <code>DUMPY</code> <code>BEGAN</code> wins all games and uses 3.89 guesses on average.</p></li><li><p>My original <code>STALE</code> <code>CHIRP</code> <code>MOUND</code> <code>GAWKY</code> wins all games and uses 3.84 (!) guesses on average.</p></li></ul><p>&#128562; &#8265;&#65039; My original gut-feel word choices did better?</p><h2>Because each word being optimal &#8800; the full set is optimal</h2><p>So it turns out it&#8217;s not enough to optimize each word; instead, we have to jointly optimize the entire sequence <code>WORD1</code> <code>WORD2</code> <code>WORD3</code> <code>WORD4</code> across all possible word sequences.</p><p>But that&#8217;s a lot of sequences! I&#8217;m not sure how much exactly 2309<sup>4</sup> is, but it&#8217;s definitely more than my computer can handle. Even doing some intelligent pruning (e.g. &#8216;a letter must not repeat in the first 3 words&#8217;) still leaves a lot of options to evaluate. What else can we do to cut it down?</p><p>What I ended up doing was ranking all words by the number of bits of information that they provide, picking the top 10-100 words at each position for a total of ~160,000 four-word combinations, and then simulating all possible games for each sequence.</p><p>After two days at 100% CPU, my computer gave me the answer:</p><ul><li><p><code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code>: 3.79991 average guesses to win.</p></li></ul><p>But there were a lot of other sequences that produced similar results. For example #2 sequence was <code>CRANE</code> <code>SPILT</code> <code>DOUGH</code> <code>BALMY</code> that took on average 3.8008 guesses to win.</p><h2>But what if I&#8217;m a smart and tailor my guesses sooner?</h2><p>Or, to be less flippant, you can often get into situations where there are more than three guesses left, but you can easily enumerate them. The simplest example is if your first guess <code>SHARE</code> results in something like </p><div class="captioned-image-container"><figure><div class="image-link image2" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cac1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 424w, https://substackcdn.com/image/fetch/$s_!cac1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 848w, https://substackcdn.com/image/fetch/$s_!cac1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 1272w, https://substackcdn.com/image/fetch/$s_!cac1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cac1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png" width="156" height="42" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:42,&quot;width&quot;:156,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1821,&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://iourikhramtsov.substack.com/i/212754173?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.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_!cac1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 424w, https://substackcdn.com/image/fetch/$s_!cac1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 848w, https://substackcdn.com/image/fetch/$s_!cac1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 1272w, https://substackcdn.com/image/fetch/$s_!cac1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F815cea16-bb19-4b5b-8fb7-39033faa9438_156x42.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></div></figure></div><p>So let&#8217;s say that we start making tailored guesses when there are five possible solutions left instead of three. How does this change our optimal sequence?</p><p>After another day at 100% CPU, I ended up with <code>TRICE</code> <code>SALON</code> <code>DUMPY</code> <code>GLOBE</code>, which solved the puzzle in 3.72 steps on average.</p><p>But <code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code> wasn&#8217;t far behind, at 3.74 average guesses, and even the original <code>STALE</code> <code>CHIRP</code> <code>MOUND</code> <code>GAWKY</code> clocked in at respectable 3.79 guesses.</p><h2>But what if the word list changes?</h2><p>That&#8217;s a good question. It wouldn&#8217;t do to have a set of words that&#8217;s hyper-optimized for Wordle but not other similar puzzles.</p><p>So I took the list of <a href="https://github.com/possibly-wrong/word-frequency">words ranked by their occurrence in Google Books</a>, and selected top 3000 five-letter words.</p><p>Redoing the same analysis here gives us a new winner: <code>SAINT</code> <code>BORED</code> <code>CLUMP</code> <code>FIGHT</code> at 3.91 guesses to win, though again, <code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code> is not far behind with 3.96 guesses (athough with 99.93% win rate), and even my original <code>STALE</code> <code>CHIRP</code> <code>MOUND</code> <code>GAWKY</code> comes in at a not-terrible 3.98 average guesses and 99.90% win rate.</p><h2>So what&#8217;s the lesson?</h2><p>So it turns out that the <em>most</em> optimal sequence really depends on how you play the game and which Worlde-like game you play.</p><p>But if you want a good-enough sequence, it looks like you can pick any three words that cover the most frequently used letters, and then a fourth word that complements the other three well.</p><p>Personally, I think I&#8217;ll try <code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code> for the next while.</p><p>So let&#8217;s say that we start making tailored guesses when there are five possible solutions left instead of three. How does this change our optimal sequence?</p><p>After another day at 100% CPU, I ended up with <code>TRICE</code> <code>SALON</code> <code>DUMPY</code> <code>GLOBE</code>, which solved the puzzle in 3.72 steps on average.</p><p>But <code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code> wasn&#8217;t far behind, at 3.74 average guesses, and even the original <code>STALE</code> <code>CHIRP</code> <code>MOUND</code> <code>GAWKY</code> clocked in at respectable 3.79 guesses.</p><h2>But what if the word list changes?</h2><p>That&#8217;s a good question. It wouldn&#8217;t do to have a set of words that&#8217;s hyper-optimized for Wordle but not other similar puzzles.</p><p>So I took the list of <a href="https://github.com/possibly-wrong/word-frequency">words ranked by their occurrence in Google Books</a>, and selected top 3000 five-letter words.</p><p>Redoing the same analysis here gives us a new winner: <code>SAINT</code> <code>BORED</code> <code>CLUMP</code> <code>FIGHT</code> at 3.91 guesses to win, though again, <code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code> is not far behind with 3.96 guesses (athough with 99.93% win rate), and even my original <code>STALE</code> <code>CHIRP</code> <code>MOUND</code> <code>GAWKY</code> comes in at a not-terrible 3.98 average guesses and 99.90% win rate.</p><h2>So what&#8217;s the lesson?</h2><p>So it turns out that the <em>most</em> optimal sequence really depends on how you play the game and which Worlde-like game you play.</p><p>But if you want a good-enough sequence, it looks like you can pick any three words that cover the most frequently used letters, and then a fourth word that complements the other three well.</p><p>Personally, I think I&#8217;ll try <code>SLANT</code> <code>PRICE</code> <code>DOUGH</code> <code>BALMY</code> for the next while.</p>]]></content:encoded></item><item><title><![CDATA[REST API design: lessons learned from going down the wrong (and right) paths]]></title><description><![CDATA[Recently I had a chance to participate a sort of retrospective at work on how we organize and write REST API endpoints.]]></description><link>https://www.i-kh.net/p/api-design-lessons-learned</link><guid isPermaLink="false">https://www.i-kh.net/p/api-design-lessons-learned</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Fri, 22 Apr 2022 19:21:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recently I had a chance to participate a sort of retrospective at work on how we organize and write REST API endpoints. That made me look back at some API design decisions I&#8217;ve made (and seen) over the years and realize that some of these choices are not at all obvious and that you often don&#8217;t see the tradeoffs until you&#8217;ve done it both ways and seen the results.</p><p>So here are some of the less obvious REST API design lessons that I&#8217;ve learned over the years.</p><h2>1. Do not nest objects in URL paths</h2><p>Suppose you have <code>task</code> objects that always belong to <code>project</code> objects. What would should be the URL to get information about a <code>task</code>? Should it be this:</p><pre><code>GET /api/projects/{projectId}/tasks/{taskId}</code></pre><p>or this?</p><pre><code>GET /api/tasks/{taskId}</code></pre><p>Having gone both ways, I now confidently think that the bottom choice is the best one. If you have a <code>taskId</code>, then <code>projectId</code> is redundant, and by including <code>projectId</code> in the URL you&#8217;re making the caller look up a piece of information that they may not have or need otherwise. And what happens when the caller provides the wrong <code>projectId</code>? Should you return <code>404 Not Found</code> even though you can unambiguously locate the task? You&#8217;ll also have to add extra validation code to check that the task is really in the right project&#8212;something that you wouldn&#8217;t need to do with the shorter version of the URL.</p><p>You may ask: &#8220;But how do you add a task to a project then?&#8221;</p><p>Well, how about this?</p><pre><code>POST /api/tasks
...
{
    &#8220;projectId&#8221;: 1234567,
    ...
}</code></pre><p>You may then ask, &#8220;But how do you look up tasks for a project if you can&#8217;t do <code>GET /api/project/{id}/tasks</code>?&#8221;</p><p>Like this:</p><pre><code>GET /api/tasks?projectId=&lt;projectId&gt;</code></pre><p>As a bonus, you get an endpoint to list <em>all</em> the tasks irrespective of which project they&#8217;re in. And this approach treats <code>projectId</code> as one of multiple optional filters that may be applied on <code>/api/tasks</code>, alongside maybe <code>status</code>, <code>assignedTo</code>, or any others.</p><h2>2. Of the 2xx HTTP status codes, you only need 200 OK</h2><p>This one wasn&#8217;t obvious to me until a coworker recently pointed out that he&#8217;s never seen a case where the caller had to make a decision based on the type of 2xx return code they got back.</p><p>And indeed, although <a href="https://www.rfc-editor.org/rfc/rfc9110.html">RFC 9116</a> &#8212; the current HTTP spec &#8212; defines <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-successful-2xx">seven different 2xx success codes</a>, in practice, the client-side code almost never needs to make a decision based on whether it receives e.g. <code>200 OK</code> or <code>201 Created</code>. Alright, in very rare cases it&#8217;s convenient when the server returns <code>204 No Content</code> when you&#8217;re debugging and trying whether the request is really supposed to be missing a body. But you can accomplish the same thing with <code>Content-Length</code> header, or by some other means.</p><p>I have, however, seen developers spend hours going back and forth on which 2xx code should be used for a specific endpoint. So to save everyone&#8217;s time, let&#8217;s just use <code>200 OK</code> and forget about the rest.</p><h2>3. Encode timestamps in a human-readable format</h2><p>If you&#8217;re sending or receiving timestamps, it may be tempting to use something like the <a href="https://currentmillis.com/">Unix epoch time in milliseconds</a> (the number of milliseconds since 00:00 UTC on Jan 1, 1970). It&#8217;s not a bad choice, and it&#8217;s quite convenient to work with.</p><p>Except it&#8217;s not human readable. Something like <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> (e.g. <code>2023&#8208;07&#8208;12T23:57:23Z</code>) is easier to read for a human, and you can even drop the colons (<code>2023&#8208;07&#8208;12T235723Z</code>) to make it URL-compatible.</p><p>It may take a bit extra work to configure your framework to emit times in the right format, but it will make using (and debugging) the API a lot easier.</p><p>By the way, don&#8217;t forget to include time zone in your timestamps, even if it&#8217;s just a <code>Z</code> at the end.</p><h2>4. Pagination: avoid offsets and provide a link to the next page</h2><p>There are broadly two ways to do pagination:</p><ul><li><p><strong>Page number and page size</strong>: e.g. <code>https://.../things?page=10&amp;pageSize=20</code>. This will work alright up to maybe page 10,000 or so, at which point, if the server is fetching the results from a database, you&#8217;ll start running into a quirk with <code>OFFSET</code> that can <a href="https://stackoverflow.com/questions/67057110/offset-fetch-is-slow-on-high-paging-value">substantially degrade performance</a>. So while this pagination approach is convenient when the results go into a paginated UI, it&#8217;s a bad idea to use it for an endpoint that will be called by export jobs or by anything else that will ask for a large number of pages with high offsets. Instead, it&#8217;s much better to use&#8230;</p></li><li><p><code>WHERE</code><strong>-based pagination</strong>: where the caller provides something akin to a <code>where</code> clause, like <code>https://.../things?fromId=12345678</code>. If this argument corresponds to a DB index, the response times should stay constant-ish as <code>fromId</code> argument increases, unlike <code>OFFSET</code> whose response times tend to increase linearly.</p></li></ul><p>Oh, and if anyone will be iterating over multiple pages of responses, it really helps to include the URL of the next page in the response body:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;json&quot;,&quot;nodeId&quot;:&quot;00e8e208-d4b9-46a5-8043-3db9681eb3c4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-json">{
    "data": [ ... ],
    "metadata": {
        "nextPage": "https://..."
    }
}</code></pre></div>]]></content:encoded></item><item><title><![CDATA[Progress in neural electrodes]]></title><description><![CDATA[Suppose you want to collect some signals from neurons in the brain.]]></description><link>https://www.i-kh.net/p/progress-in-neural-electrodes</link><guid isPermaLink="false">https://www.i-kh.net/p/progress-in-neural-electrodes</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 28 Jun 2021 00:34:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!D9D1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Suppose you want to collect some signals from neurons in the brain. What kind of wire should you stick into the brain to do that? Could it be just any wire, or do you need some special brain-grade wire?</p><p>That&#8217;s something that I&#8217;ve been curious about for a while now, so I&#8217;ve read a bunch of papers on the subject.</p><h2>Metal electrodes</h2><p>Surprisingly, off-the-shelf <a href="https://www.remingtonindustries.com/magnet-wire/magnet-wire-200c-44-awg-polyamideimide-5-spool-sizes/">44 AWG insulated copper wire</a> is not a completely terrible choice. Its 51&#956;m diameter (plus insulation) is a bit on the high end for a typical intracortical electrode, but it&#8217;s about the right order of magnitude. If you stick it in, for a short time it has a decent chance of picking up electric spikes that nearby neurons send when they get excited.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D9D1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D9D1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 424w, https://substackcdn.com/image/fetch/$s_!D9D1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 848w, https://substackcdn.com/image/fetch/$s_!D9D1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!D9D1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D9D1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg" width="1456" height="1134" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1134,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D9D1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 424w, https://substackcdn.com/image/fetch/$s_!D9D1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 848w, https://substackcdn.com/image/fetch/$s_!D9D1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!D9D1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82f36db4-0043-41a5-8b99-d96bccf7825a_3409x2655.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>But it&#8217;s still a terrible choice. First, the copper will quickly oxidize and corrode in the brain&#8217;s electrolyte-rich fluid. And second, copper is toxic to the neural tissue. So don&#8217;t put copper electrodes into anyone you love.</p><p>Okay, let&#8217;s try something else. How about an off-the-shelf <a href="https://wireandstuff.co.uk/product/0-04mm-46-awg-ss316l-marine-grade-stainless-steel-wire-596-83-ohms-m/">stainless steel 40&#956;m wire</a>? These are actually a legit choice, once you figure out how to insulate and sharpen them. In 1958, at UCLA, Felix Strumwasser sharpened 80&#956;m stainless steel wires with hydrochloric acid and <a href="https://science.sciencemag.org/content/127/3296/469">used them to record spikes</a> in neurons of ground squirrels for over a week. The wires were likely insulated by dipping them into lacquer, <a href="https://www.nature.com/articles/182962a0">as described by Green</a>, also from UCLA, later the same year.</p><p>However, the most popular electrode metal these days seems to be tungsten or <a href="https://www.fishersci.ca/shop/products/platinum-wire-0-025mm-0-001-in-dia-99-95-metals-basis-alfa-aesar-3/p-4782059#?keyword=platinum+wire">platinum</a>. Though noticeably pricier, it seems that these give you a better signal-to-noise ratio without messing with the brain chemistry.</p><p>So let&#8217;s say we get some platinum or wire, coat it with tissue-friendly <a href="https://en.wikipedia.org/wiki/Parylene">parylene C</a> for insulation, and then expose and sharpen its tip. Are we good?</p><p>Not quite.</p><h2>Multiple electrodes</h2><p>According to <a href="https://link.springer.com/chapter/10.1007/978-1-4939-1969-7_1">Techniques for Large-Scale Multiunit Recording</a>, inserting one electrode by itself is often not that useful. First, in addition to neural signals, the electrode will also pick up the background noise, including the AC power lines in the walls. Second, we often want to collect spikes from multiple sites to observe the behavior of more neurons.</p><p>The simplest way to increase the number of electrodes is to twist a few of them together, insert them, and measure the difference in voltage between some of the pairs. Taking the difference in voltage between the electrodes helps not only remove the background noise but also isolate individual neurons because the electrodes closer to the spiking neuron will register higher voltage swings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qY5-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qY5-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 424w, https://substackcdn.com/image/fetch/$s_!qY5-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 848w, https://substackcdn.com/image/fetch/$s_!qY5-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 1272w, https://substackcdn.com/image/fetch/$s_!qY5-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qY5-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png" width="589" height="307" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57605b00-cee1-453a-8be3-36c397a45be6_589x307.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:307,&quot;width&quot;:589,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A tetrode (a probe with four electrodes) can distinguish spikes from different neurons in its neighborhood because the electrodes closer to the neuron will pick up bigger voltage spikes. Courtesy of Stuartlayton via Wikipedia https://en.wikipedia.org/wiki/File:HippocampalTetrodeExample.png.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A tetrode (a probe with four electrodes) can distinguish spikes from different neurons in its neighborhood because the electrodes closer to the neuron will pick up bigger voltage spikes. Courtesy of Stuartlayton via Wikipedia https://en.wikipedia.org/wiki/File:HippocampalTetrodeExample.png." title="A tetrode (a probe with four electrodes) can distinguish spikes from different neurons in its neighborhood because the electrodes closer to the neuron will pick up bigger voltage spikes. Courtesy of Stuartlayton via Wikipedia https://en.wikipedia.org/wiki/File:HippocampalTetrodeExample.png." srcset="https://substackcdn.com/image/fetch/$s_!qY5-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 424w, https://substackcdn.com/image/fetch/$s_!qY5-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 848w, https://substackcdn.com/image/fetch/$s_!qY5-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.png 1272w, https://substackcdn.com/image/fetch/$s_!qY5-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57605b00-cee1-453a-8be3-36c397a45be6_589x307.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A tetrode (a probe with four electrodes) can distinguish spikes from different neurons in its neighborhood because the electrodes closer to the neuron will pick up bigger voltage spikes. Courtesy of Stuartlayton via Wikipedia https://en.wikipedia.org/wiki/File:HippocampalTetrodeExample.png.</figcaption></figure></div><p>The next step up is electrode arrays, which help measure signals over larger areas or a range of depths. Here, silicon probes became popular, like the widely used <a href="https://www.blackrockmicro.com/products/#electrodes">Utah array</a> with as many as 100 needle-like electrodes, or a <a href="https://www.neuropixels.org/">Neuropixels probe</a>, which has a single shank with 960 electrodes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dm-H!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dm-H!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 424w, https://substackcdn.com/image/fetch/$s_!dm-H!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 848w, https://substackcdn.com/image/fetch/$s_!dm-H!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 1272w, https://substackcdn.com/image/fetch/$s_!dm-H!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dm-H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png" width="843" height="492" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:843,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;2mm x 2mm Utah array. Image from patent US5215088A.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="2mm x 2mm Utah array. Image from patent US5215088A." title="2mm x 2mm Utah array. Image from patent US5215088A." srcset="https://substackcdn.com/image/fetch/$s_!dm-H!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 424w, https://substackcdn.com/image/fetch/$s_!dm-H!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 848w, https://substackcdn.com/image/fetch/$s_!dm-H!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.png 1272w, https://substackcdn.com/image/fetch/$s_!dm-H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38d53d25-db69-481a-9960-67ff13dfcffe_843x492.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">2mm x 2mm Utah array. Image from patent US5215088A.</figcaption></figure></div><p>Utah array in particular featured in a number of really cool experiments, like <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5516547/">this BrainGate experiment</a> where researchers implanted Utah arrays into a tetraplegic individual and connected them to electrodes implanted in the hand muscles, allowing the subject to move his hands.</p><p>However, it turns out that silicon probes have their own problems, and aren&#8217;t the best thing to insert into the brain either.</p><h2>Biocompatibility</h2><p>So what&#8217;s the problem with the silicon probes?</p><p>Well, <a href="https://iopscience.iop.org/article/10.1088/1741-2560/8/2/025027/meta">a number</a> <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4868924/">of studies</a> <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2724357/">have shown</a> that over the months after the implantation, the signal from the electrodes weakens, and some of the previously working electrodes go silent.</p><p>And metal electrodes aren&#8217;t better either. For example, <a href="https://iopscience.iop.org/article/10.1088/1741-2560/9/5/056015">this study</a> tracked the performance of 50&#956;m tungsten electrodes over 9 months, and found that within the first few months, many electrodes could no longer detect spikes and the few that could, had much weaker or unstable signals. In some individual rats (who got the arrays implanted), by the end of the experiment, zero out of sixteen electrodes could detect useful signals</p><p>To be clear, all of these studies showed that in almost all cases it was still possible to get useful signals at the end of the experiment, just that over time the signal quality got noticeably worse.</p><p>So can we do better?</p><p>A lot of studies have dug into why the signal quality decreases. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8152109/">This recent review</a> (section 2) summarizes the causes: (1) the electrodes create small stab wounds on the way in, damaging the tissue and the blood vessels; (2) electrode bodies cause chronic inflammation that results in a scar that surrounds the probe and reduces the signal quality; (3) all of the above cause nearby neurons to die or migrate away from the insertion site.</p><p>This can be made worse by the rigid bodies of the probes. Mammalian brains naturally move inside the skull, swelling with each pulse of blood from the heart, and rigid metal and silicon electrodes cannot deform at the same rate as the brain tissue.</p><p>To top it off, poorly chosen insulation can crack or detach from the probe, letting carefully collected signals leak back into the surrounding tissue.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NZMT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NZMT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NZMT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NZMT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NZMT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NZMT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg" width="356" height="267" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:267,&quot;width&quot;:356,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Insulation detaching from a tungsten electrode. Abhishek Prasad et al 2012 J. Neural Eng. 9 056015.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Insulation detaching from a tungsten electrode. Abhishek Prasad et al 2012 J. Neural Eng. 9 056015." title="Insulation detaching from a tungsten electrode. Abhishek Prasad et al 2012 J. Neural Eng. 9 056015." srcset="https://substackcdn.com/image/fetch/$s_!NZMT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NZMT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NZMT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NZMT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c95e483-7da8-4b9c-b51a-21ea0f6b2b34_356x267.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Insulation detaching from a tungsten electrode. Abhishek Prasad et al 2012 J. Neural Eng. 9 056015.</figcaption></figure></div><h2>Smaller, softer electrodes</h2><p>Various recent reviews, such as <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8152109/">this one</a> and <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7523527/">this one</a>, suggest that the best electrodes would be:</p><ul><li><p>Made of very thin wires, comparable in size to neuron&#8217;s appendages (<a href="http://localhost:4000/2020/08/26/the-magic-of-ion-channels/">axons and dendrites</a>) - that&#8217;s &lt;10&#956;m across.</p></li><li><p>Soft, bending as easily as cortical tissue.</p></li><li><p>Covered in well-attached insulation that won&#8217;t agitate neurons or other cells in the brain.</p></li><li><p>&#8220;Floating&#8221;, that is, loosely attached to the skull or signal processing circuitry, allowing the electrodes to move as the brain moves.</p></li></ul><p>Over the last decade, a number of electrodes satisfying these conditions started appearing:</p><ul><li><p><a href="https://www.biorxiv.org/content/10.1101/460949v1.full">NeuroRoots</a>, made of 100nm-thick platinum wires encapsulated in parylene-C insulation; total cross-section: 1.5&#956;m x 7&#956;m.</p></li><li><p>Elon Musk-sponsored <a href="https://www.jmir.org/2019/10/e16194/">Neuralink</a>, which uses insulated gold &#8220;threads&#8221; that are 4-6&#181;m-thick and 5-50&#181;m wide, depending on the number of electrodes per thread.</p></li><li><p><a href="https://advances.sciencemag.org/content/5/3/eaav2842">Neurotassels</a> uses 100nm-thick gold electrodes wrapped in polyimide insulation; total cross-section: 3&#181;m x 12&#181;m.</p></li><li><p>Ultra-soft <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5512864/">conducting polymer</a> microelectrodes, though at 125&#181;m these were much thicker than others on this list.</p></li><li><p><a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3524530/">Carbon fiber</a> electrodes around 9-10&#181;m in diameter.</p></li><li><p>And a variety of other wires, meshes, and probes.</p></li></ul><p>Most of these came with a study showing how much they outperform the previous generation of electrodes, and how little damage they do in a rat brain. In the case of something like NeuroRoots, it looks pretty impressive on paper: after 7 weeks, all 32 of the 32 implanted electrodes could pick up signals nearly as well as on the day they were implanted. In the case of the conducting polymer above, the study compared it to much thicker tungsten electrodes, making the comparison somewhat unfair.</p><h2>Conclusions</h2><p>So basically, yes, you would need a brain-grade wire to collect signals from neurons, and we&#8217;re still working out the specifics of what makes the wire &#8220;brain-grade&#8221;.</p><p>With the progress above made in the 2010s, I&#8217;m looking forward to seeing what the 2020s will bring.</p>]]></content:encoded></item><item><title><![CDATA[Getting started with FPGAs and Verilog]]></title><description><![CDATA[I&#8217;ve been curious about FPGAs since I first heard about them over ten years ago, and over the past month I finally gave them a try for a couple personal projects.]]></description><link>https://www.i-kh.net/p/getting-started-with-fpga-and-verilog</link><guid isPermaLink="false">https://www.i-kh.net/p/getting-started-with-fpga-and-verilog</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Wed, 26 May 2021 12:08:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tLvo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve been curious about <a href="https://en.wikipedia.org/wiki/Field-programmable_gate_array">FPGAs</a> since I first heard about them over ten years ago, and over the past month I finally gave them a try for a couple personal projects.</p><p>The FPGAs are certainly&#8230; different from any other kind of programming, and it took a bit of effort and troubleshooting to get my FPGA calculator working. If you&#8217;re interested in getting into FPGAs, here are a few tips below.</p><h2>1. The basics</h2><p>Programming FPGAs is different from programming in JavaScript, C#, or C. There are no levels of abstraction between you and the hardware, so it&#8217;s essential to learn the foundations of digital logic.</p><p>For me, <a href="https://artofelectronics.net/">The Art of Electronics</a> worked very well &#8212; specifically, chapters 10-14.</p><p>The book first introduces the basic logic circuit elements, and then builds up to other components and concepts: flip-flops, clocking, different logic families, logic interfacing, three-state outputs, busses, etc.</p><p>Almost all of it was useful when I got to programming the FPGA.</p><p>If textbooks are not your thing, there are <a href="https://www.youtube.com/results?search_query=intro+to+digital+logic">lots of YouTube videos</a> covering the same subjects.</p><h2>2. Verilog</h2><p>There are three main hardware definition languages: Verilog, VHDL, and SystemVerilog. Either one is a valid choice, though I found that for Digilent and Xilinx (my choice of FPGA boards and chips) there were more Verilog examples, so I went with that.</p><p>Unfortunately, Verilog just doesn&#8217;t have as much great documentation as, say, TypeScript or C#. The best I could find were these two websites:</p><ul><li><p><a href="https://www.chipverify.com/verilog/verilog-tutorial">Chipverify Verilog Tutorial</a></p></li><li><p><a href="https://verilogguide.readthedocs.io/en/latest/verilog/overview.html">This Verilog guide</a> on readthedocs.io.</p></li></ul><p>I&#8217;ve read these before I started programming, and referred back to them a number of times afterwards.</p><h2>3. The board</h2><p>You can try buying an FPGA chip and soldering it to a board yourself, but it&#8217;s much easier to get a starter board that already includes all the necessary components such as configuration flash memory, USB interface, and voltage regulator.</p><p>For starter boards, I liked <a href="https://reference.digilentinc.com/programmable-logic/start">Digilent</a> boards the most and went with <a href="https://reference.digilentinc.com/programmable-logic/cmod-a7/start">Cmod A7</a> that had a Xilinx <a href="https://www.xilinx.com/products/silicon-devices/fpga/artix-7.html">Artix-7</a> chip on it. It was powerful enough to fit the projects I wanted to build with room to spare, and it could plug into a breadboard.</p><p>Alternatively, if you&#8217;re looking to spend less, <a href="https://reference.digilentinc.com/programmable-logic/cmod-s7/start">Cmod S7</a> seems like a decent choice, and if you&#8217;re looking for more power, there&#8217;s something like <a href="https://reference.digilentinc.com/programmable-logic/arty-a7/start">Arty A7</a>.</p><h2>4. Making the LED blink</h2><p>Now we have everything we need to take FPGA for a test drive.</p><p>If you&#8217;ve gone with a Digilent board, the next step that worked for me was to go through the <a href="https://reference.digilentinc.com/learn/software/tutorials/verilog-project-2/start">Getting started with Vivado</a> guide from Digilent.</p><p>Be aware that there are a few quirks that you may run into:</p><ul><li><p>The LED port name in the module definition must exactly match the port name in the constraints file. For example, it can&#8217;t be <code>led[0]</code> in the constraints file and <code>led</code> in the module definitions - you&#8217;ll get an error when generating the bitstream.</p></li><li><p>Xilinx wants you to create an account before using Vivado, and they want you to enter something that looks like a real address when doing so. They&#8217;ll check the address, but not too thoroughly. You&#8217;ll need to log into the account when starting Vivado.</p></li></ul><h2>5. Now build your first project.</h2><p>From here, build whatever you were thinking of.</p><p>If you&#8217;re looking for an idea for a simple project before moving on to something more interesting, I found a calculator to have just the right amount of complexity:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tLvo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tLvo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tLvo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tLvo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tLvo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tLvo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!tLvo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tLvo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tLvo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tLvo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2b1e1ac-d356-4a0e-ac28-d8c36d2e79e9_3763x2150.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>From here on, the things that helped me the most were:</p><ul><li><p>Carefully reading the documentation and the guides, as they often contain the answers you&#8217;re looking for. For example, each Digilent board has a <a href="https://reference.digilentinc.com/programmable-logic/cmod-a7/reference-manual">detailed reference manual</a> that explains how to work with each component that&#8217;s on the board.</p></li><li><p>The chip manufacturer has detailed guides as well. For example, if you&#8217;re looking to change the clock frequency on your FPGA chip, or want to work with multiple clock frequencies, Xilinx has a very thorough guide on <a href="https://www.xilinx.com/support/documentation/ip_documentation/mmcm_module.pdf">working with Mixed Mode Clock Managers</a>.</p></li><li><p>If you run into a problem, keep simplifying your logic until it starts working. For example, when I was having trouble sending data over the USB/UART link, I ended up removing all of my logic and just tying the RXD (send) wire to TXD (receive) wire to make sure that I could echo the characters through it using the COM terminal. Turns out I couldn&#8217;t because I mixed up which wire was the input and which was the output. The rest of my logic was correct.</p></li><li><p>If you get stuck, like everywhere else, use Google. Someone has run into a similar problem. If you don&#8217;t find the exact solution, at least you may get an idea that you can try next.</p></li></ul><h2>6. This will save you days</h2><p>I was going to lump this with the tips above, but this deserves its own section.</p><p>Put</p><pre><code>`default_nettype none</code></pre><p>at the beginning of every Verilog file (yes, including the backtick), and</p><pre><code>`default_nettype wire</code></pre><p>at the end.</p><p>This is because by default, if you make a typo in a variable name, Verilog will assume that you&#8217;ve defined a new variable of type <code>wire</code>. Because of this, I literally spent a day debugging a problem that was caused by a typo.</p><p>If you put <code>`default_type none</code>, Verilog will complain that it doesn&#8217;t know the variable type and will bring your attention to the typo.</p><p>The closing <code>`default_nettype wire</code> is necessary because apparently some of Xilinx&#8217;s own modules (called &#8220;IP&#8221; in FPGA terminology) rely on implicitly defined variable types.</p>]]></content:encoded></item><item><title><![CDATA[Human vision system - a simple description]]></title><description><![CDATA[So when we see something in front of us, like a pencil, how exactly does the brain understand that yep, that&#8217;s a pencil?]]></description><link>https://www.i-kh.net/p/human-vision-system-an-overview</link><guid isPermaLink="false">https://www.i-kh.net/p/human-vision-system-an-overview</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 01 Mar 2021 01:45:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!818L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!818L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!818L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 424w, https://substackcdn.com/image/fetch/$s_!818L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 848w, https://substackcdn.com/image/fetch/$s_!818L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 1272w, https://substackcdn.com/image/fetch/$s_!818L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!818L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png" width="1456" height="731" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:731,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!818L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 424w, https://substackcdn.com/image/fetch/$s_!818L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 848w, https://substackcdn.com/image/fetch/$s_!818L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 1272w, https://substackcdn.com/image/fetch/$s_!818L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86bc1629-19d3-4367-83d8-b651a8540614_2897x1454.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So when we see something in front of us, like a pencil, how exactly does the brain understand that yep, that&#8217;s a pencil?</p><p>Like, what is the detailed sequence of steps that happens? The eyes presumably convert the light to neural signals (how?), then these get sent to the brain (where?), and then the brain does&#8230; what?</p><p>I&#8217;ve been reading through a bunch of neuroscience textbooks and papers for the past six months, and I think I&#8217;m at the point where I&#8217;ve now got the whole picture.</p><p>So here are the core pieces of this picture, with a lot of details omitted to fit it into a short blog post.</p><p>Let&#8217;s start with the input.</p><h2>What exactly do the eyes do?</h2><p>The main output of the eyes are the neurons called <em>ganglion cells</em> that live in the thin layer of tissue at the back of the eye. To grossly oversimplify, these ganglion cells transmit the brightness of each pixel of the picture that&#8217;s projected onto the back of the eye, though the reality is <a href="https://i-kh.net/2020/10/31/retina-circuits-more-than-just-pixels/">much more complex</a>.</p><p>To transmit this information, the neurons use spikes of voltage &#8211; that&#8217;s when the voltage between the inside and the outside of the cell suddenly rises from somewhere around -60 mV to around 0 mV and falls back down over the course of about a millisecond.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!23cq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!23cq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 424w, https://substackcdn.com/image/fetch/$s_!23cq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 848w, https://substackcdn.com/image/fetch/$s_!23cq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 1272w, https://substackcdn.com/image/fetch/$s_!23cq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!23cq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png" width="1456" height="846" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:846,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!23cq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 424w, https://substackcdn.com/image/fetch/$s_!23cq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 848w, https://substackcdn.com/image/fetch/$s_!23cq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.png 1272w, https://substackcdn.com/image/fetch/$s_!23cq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5d37fd7-bb7c-48d6-9826-923f9e8b65ef_2503x1454.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the eyes, these spikes are caused by light-sensitive proteins called opsins that live in cells of another type, the <em>photoreceptors</em>. When photons hit the photoreceptor cells, the opsins in these cells absorb the photons and slightly change their structure, which causes a rapid cascade of chemical reactions across a few cells. At the end of this series of reactions, the ganglion cells let in some positively charged ions, raise their internal voltage, and start a spike.</p><p>(I&#8217;ve written more about how the ions cause spikes in <a href="https://i-kh.net/2020/08/26/the-magic-of-ion-channels/">another post</a>)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fDrR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fDrR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 424w, https://substackcdn.com/image/fetch/$s_!fDrR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 848w, https://substackcdn.com/image/fetch/$s_!fDrR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 1272w, https://substackcdn.com/image/fetch/$s_!fDrR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fDrR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png" width="1456" height="542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:542,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!fDrR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 424w, https://substackcdn.com/image/fetch/$s_!fDrR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 848w, https://substackcdn.com/image/fetch/$s_!fDrR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.png 1272w, https://substackcdn.com/image/fetch/$s_!fDrR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9de19a1-ae59-4fb7-b594-7d4e7d2a40c6_3397x1265.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The whole system is set up to handle different volumes of light: the more light is shining on the photoreceptors, the more spikes are produced by the ganglion cells.</p><p>So, to grossly oversimplify even more, more light =&gt; more spikes in the ganglion cells.</p><p>And now what?</p><h2>Where do the signals go?</h2><p>The ganglion cells live at the back of the eyes, but they have long output extensions (axons) that run from the eye, through the optic nerve, and right into the center of the brain. That&#8217;s where the thalamus &#8211; the brain&#8217;s main switchboard &#8211; is located.</p><p>In an adult human, that&#8217;s about 10 cm or 4 in of length, and that&#8217;s far from the record for the length of a neuron. The spikes travel along the full length.</p><p>One of the interesting things that happen along the way is that the optic nerves cross at about the half-way mark, and the neurons from the left half of each eye end up traveling to the left half of the brain, while the neurons from the right half of each eye go to the right.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gJT2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gJT2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 424w, https://substackcdn.com/image/fetch/$s_!gJT2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 848w, https://substackcdn.com/image/fetch/$s_!gJT2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 1272w, https://substackcdn.com/image/fetch/$s_!gJT2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gJT2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png" width="360" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Source: Gray's anatomy, fig. 722, https://www.bartleby.com/107/illus722.html&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Source: Gray's anatomy, fig. 722, https://www.bartleby.com/107/illus722.html" title="Source: Gray's anatomy, fig. 722, https://www.bartleby.com/107/illus722.html" srcset="https://substackcdn.com/image/fetch/$s_!gJT2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 424w, https://substackcdn.com/image/fetch/$s_!gJT2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 848w, https://substackcdn.com/image/fetch/$s_!gJT2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.png 1272w, https://substackcdn.com/image/fetch/$s_!gJT2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb91dce81-d44e-4c98-8c07-1e70bd93556c_360x500.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: Gray's anatomy, fig. 722, https://www.bartleby.com/107/illus722.html</figcaption></figure></div><p>This way, each hemisphere of the brain will be able to construct a stereo picture of each half of the visual field.</p><p>From the thalamus, a new set of neurons picks up the same information and forwards it to the back of the brain - the occipital lobe - where the brain will do its magic.</p><h2>And the brain does&#8230; what?</h2><p>In the brain, visual processing is done through a sequence of visual cortex areas - V1, V2, V3, etc, each of which extracts progressively more complex features from the original signal.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pvKm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pvKm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 424w, https://substackcdn.com/image/fetch/$s_!pvKm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 848w, https://substackcdn.com/image/fetch/$s_!pvKm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!pvKm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pvKm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png" width="1456" height="723" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:723,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Visual processing pipeline. Adapted from https://doi.org/10.1016/S1364-6613%2898%2901171-1, https://doi.org/10.1016/j.tics.2012.03.003&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Visual processing pipeline. Adapted from https://doi.org/10.1016/S1364-6613%2898%2901171-1, https://doi.org/10.1016/j.tics.2012.03.003" title="Visual processing pipeline. Adapted from https://doi.org/10.1016/S1364-6613%2898%2901171-1, https://doi.org/10.1016/j.tics.2012.03.003" srcset="https://substackcdn.com/image/fetch/$s_!pvKm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 424w, https://substackcdn.com/image/fetch/$s_!pvKm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 848w, https://substackcdn.com/image/fetch/$s_!pvKm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.png 1272w, https://substackcdn.com/image/fetch/$s_!pvKm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c9893a7-5dde-4686-bf53-633cc71fb6e3_2670x1326.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Visual processing pipeline. Adapted from https://doi.org/10.1016/S1364-6613%2898%2901171-1, https://doi.org/10.1016/j.tics.2012.03.003</figcaption></figure></div><p>The first one of these, V1, is located right at the back of the brain; it represents nearly pixel-for-pixel what the eye sees - that is, the neighboring neurons in V1 represent neighboring points on the image.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2Kbt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2Kbt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 424w, https://substackcdn.com/image/fetch/$s_!2Kbt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 848w, https://substackcdn.com/image/fetch/$s_!2Kbt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 1272w, https://substackcdn.com/image/fetch/$s_!2Kbt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2Kbt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png" width="1456" height="912" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:912,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Left visual field is faithfully represented in the left V1 area, except the center of vision is exaggerated. Adapted from http://fourier.eng.hmc.edu/e180/lectures/v1/node3.html&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Left visual field is faithfully represented in the left V1 area, except the center of vision is exaggerated. Adapted from http://fourier.eng.hmc.edu/e180/lectures/v1/node3.html" title="Left visual field is faithfully represented in the left V1 area, except the center of vision is exaggerated. Adapted from http://fourier.eng.hmc.edu/e180/lectures/v1/node3.html" srcset="https://substackcdn.com/image/fetch/$s_!2Kbt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 424w, https://substackcdn.com/image/fetch/$s_!2Kbt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 848w, https://substackcdn.com/image/fetch/$s_!2Kbt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.png 1272w, https://substackcdn.com/image/fetch/$s_!2Kbt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F435a18ed-b08e-4290-bccb-1266bdf088f3_2321x1454.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Left visual field is faithfully represented in the left V1 area, except the center of vision is exaggerated. Adapted from http://fourier.eng.hmc.edu/e180/lectures/v1/node3.html</figcaption></figure></div><p>In V1, a series of neural connections detect basic features like edges, colors, directions, or motion in each patch of the visual field. If the neurons responsible for detecting a specific feature detect it, they fire a series of spikes, letting the downstream areas know what they found.</p><p>The downstream areas - V2, V3, etc. - extract progressively more and more complex features over larger and larger areas.</p><p>If you&#8217;re familiar with Convolutional Neural Networks (if you&#8217;re not, here&#8217;s <a href="https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53">a good explainer</a>), that&#8217;s pretty much exactly what&#8217;s going on here.</p><p>Early on, the processing path splits into two branches: the bottom one that&#8217;s focused on recognizing objects, and the top one that&#8217;s focused on building a mental picture of space and motion.</p><p>At the end of the bottom branch are the areas that recognize faces, places, or objects, including the pencil that we started with.</p><p>Here, if the final collection of features extracted along the way add up to a specific known object, a collection of neurons that are associated with that object fires spikes to other areas of the brain, triggering appropriate emotions, thoughts, memories, and other associations that we may need at the moment.</p>]]></content:encoded></item><item><title><![CDATA[Image stabilization - in humans]]></title><description><![CDATA[As I read more neuroscience, I run into more interesting neural circuits.]]></description><link>https://www.i-kh.net/p/image-stabilization-in-humans</link><guid isPermaLink="false">https://www.i-kh.net/p/image-stabilization-in-humans</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Fri, 19 Feb 2021 01:09:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FQ1o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As I read more neuroscience, I run into more interesting neural circuits. One of these circuits is the Vestibulo-Ocular Reflex (VOR) that helps us keep the eyes locked on a target when the head moves.</p><p>What&#8217;s interesting about it are both its simple wiring (at first glance), and the extensive hidden support circuitry that can tell us more about how the brain works.</p><p>VOR is not the only circuit that helps us keep our eyes locked on target; there are others that work in parallel. I suspect that they probably use the same underlying principles.</p><p>(Note: some links here are behind a paywall. Remember that it&#8217;s illegal to go to Sci-Hub and search for the DOI link of the article to get free access to it.)</p><h2>So what&#8217;s Vestibulo-Ocular Reflex?</h2><p>Pick a point on the screen, and while looking at it, turn your head left to right. Your head will move, but your eyes will stay locked onto that point.</p><p>For that to happen, the muscles that control your eyeballs need to change their tension at exactly the right time and by exactly the right amount to compensate for the movement of the head.</p><p>While at first glance that may seem tricky, in reality, the brain deals with it the same way as the smartphone: it just uses our internal accelerometer, the <em>vestibular apparatus</em>, pictured below in the red box.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FQ1o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FQ1o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!FQ1o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!FQ1o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!FQ1o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FQ1o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The vestibular organ is the collection of tubes in the red box. Source: Blausen.com staff (2014). \&quot;Medical gallery of Blausen Medical 2014\&quot;. WikiJournal of Medicine 1 (2). DOI:10.15347/wjm/2014.010. ISSN 2002-4436&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="The vestibular organ is the collection of tubes in the red box. Source: Blausen.com staff (2014). &quot;Medical gallery of Blausen Medical 2014&quot;. WikiJournal of Medicine 1 (2). DOI:10.15347/wjm/2014.010. ISSN 2002-4436" title="The vestibular organ is the collection of tubes in the red box. Source: Blausen.com staff (2014). &quot;Medical gallery of Blausen Medical 2014&quot;. WikiJournal of Medicine 1 (2). DOI:10.15347/wjm/2014.010. ISSN 2002-4436" srcset="https://substackcdn.com/image/fetch/$s_!FQ1o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!FQ1o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!FQ1o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!FQ1o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ecea041-382f-48ba-8844-c697f6079170_1920x1080.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The vestibular organ is the collection of tubes in the red box. Source: Blausen.com staff (2014). "Medical gallery of Blausen Medical 2014". WikiJournal of Medicine 1 (2). DOI:10.15347/wjm/2014.010. ISSN 2002-4436</figcaption></figure></div><h2>From accelerometer to muscles</h2><p>From the vestibular organ, there&#8217;s a simple three-neuron-long connection that feeds the accelerometer signal to the muscles that move the eyes, first documented <a href="https://doi.org/10.1001/archneurpsyc.1933.02240140009001">in the 1930s</a>. We can follow it to see what it does.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NkHE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NkHE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 424w, https://substackcdn.com/image/fetch/$s_!NkHE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 848w, https://substackcdn.com/image/fetch/$s_!NkHE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 1272w, https://substackcdn.com/image/fetch/$s_!NkHE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NkHE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NkHE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 424w, https://substackcdn.com/image/fetch/$s_!NkHE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 848w, https://substackcdn.com/image/fetch/$s_!NkHE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.png 1272w, https://substackcdn.com/image/fetch/$s_!NkHE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c3aac0c-43ca-439e-aff6-13a0417b4ef4_2160x2160.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The neurons coming out of the vestibular organ output a steady stream of electric spikes. When the head turns left, the left vestibular neuron starts producing more electric spikes, and the right one - less. When the head stops moving, both vestibular neurons go back to the equal rate of spikes. If the head turns right, the opposite happens.</p><p>The signals from the vestibular neurons end up in the brainstem, the more basic part of the brain that sits between the cerebral cortex and the spine. There, another set of neurons directly connect them to the pools of motor neurons that move the eye muscles.</p><p>The muscle neurons, in turn, work according to rules we won&#8217;t go into right now, but it&#8217;s safe to simplify and say that the more excited they get the more the eye muscles contract.</p><p>So basically, when the head turns left, the increased rate of spikes from the left vestibular neuron is directly fed into the motorneurons that turn the eyes right.</p><p>End-to-end, this circuit is very fast. Experiments show that once the head starts turning, it takes less than 10 ms for the muscles to engage.</p><p>(Btw, Wikipedia has a <a href="https://en.wikipedia.org/wiki/Vestibulo%E2%80%93ocular_reflex">different wiring diagram</a>; I&#8217;ve seen it drawn both ways in papers. In practice, the result is the same either way.)</p><h2>Complication #1: the neural integrator</h2><p>So, on the surface, it seems that we&#8217;re done. The acceleration output feeds directly into the motorneurons, the eyes move, and we&#8217;re happy.</p><p>But here&#8217;s the problem: when the head is done turning, the vestibular organs go back to signaling at the base rate. Then the tension in the eye muscles goes back to equal, pointing the eyes straight. That&#8217;s not what we were hoping to see.</p><p>To fix that, we need to add a <em>neural integrator</em> to the picture.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mJZ6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mJZ6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 424w, https://substackcdn.com/image/fetch/$s_!mJZ6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 848w, https://substackcdn.com/image/fetch/$s_!mJZ6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 1272w, https://substackcdn.com/image/fetch/$s_!mJZ6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mJZ6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png" width="879" height="923" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:923,&quot;width&quot;:879,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mJZ6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 424w, https://substackcdn.com/image/fetch/$s_!mJZ6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 848w, https://substackcdn.com/image/fetch/$s_!mJZ6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.png 1272w, https://substackcdn.com/image/fetch/$s_!mJZ6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8d85a6b-ab18-4303-a735-0c0b3a547052_879x923.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The neural integrator does this: (1) it collects the total velocity signal sent to the eye muscles, and (2) outputs the spikes at exactly the right rate to keep the eyes pointed in the right direction.</p><p>I.e. it literally integrates the angular velocity to come up with the final position.</p><p>Our best guess that the integrator works using some clever mutually inhibitory feedback. If the left vestibular neuron sends more spikes, the right half of the neural integrator gets more excited, and ends up inhibiting the left half more, which ends up inhibiting the right half less. <a href="https://doi.org/10.1016/B978-008045046-9.01434-0">This entry</a> in the Encyclopedia of Neuroscience describes the math in more detail.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0zoy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0zoy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 424w, https://substackcdn.com/image/fetch/$s_!0zoy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 848w, https://substackcdn.com/image/fetch/$s_!0zoy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 1272w, https://substackcdn.com/image/fetch/$s_!0zoy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0zoy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png" width="261" height="447" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:447,&quot;width&quot;:261,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A sketch of a neural integrator model. Source: Neural Integrator Models, Encyclopedia of Neuroscience (2009), https://doi.org/10.1016/B978-008045046-9.01434-0&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A sketch of a neural integrator model. Source: Neural Integrator Models, Encyclopedia of Neuroscience (2009), https://doi.org/10.1016/B978-008045046-9.01434-0" title="A sketch of a neural integrator model. Source: Neural Integrator Models, Encyclopedia of Neuroscience (2009), https://doi.org/10.1016/B978-008045046-9.01434-0" srcset="https://substackcdn.com/image/fetch/$s_!0zoy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 424w, https://substackcdn.com/image/fetch/$s_!0zoy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 848w, https://substackcdn.com/image/fetch/$s_!0zoy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.png 1272w, https://substackcdn.com/image/fetch/$s_!0zoy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a7bb227-1cd1-45ed-90a2-c97ee3c2a050_261x447.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A sketch of a neural integrator model. Source: Neural Integrator Models, Encyclopedia of Neuroscience (2009), https://doi.org/10.1016/B978-008045046-9.01434-0</figcaption></figure></div><p>Some papers indicate that there may be a <a href="https://doi.org/10.1007/978-3-540-29678-2_3916">number of different neurons</a> involved, and this may be a multi-stage process.</p><p>(On a tangent: there isn&#8217;t just one neural integrator. There seem to be a number of them in the brain; for example, if you close your eyes and move around the room, a part of the cerebral cortex will keep an estimate of your position from your motion, though it won&#8217;t be very accurate. One of the papers linked above even argues that accumulating the evidence for two alternatives in a decision process could also be considered an integrator.)</p><h2>Complication #2: controlling the gain</h2><p>Setting the neural integrator aside, here&#8217;s a different question: why is it that a 5&#176; turn of the head causes a 5&#176; turn of the eyes? What makes it not be 4&#176;, or 10&#176;? Are we just lucky that the neural connections work out to be exactly right?</p><p>Turns out, <a href="https://www.nature.com/articles/s41583-020-00392-x">there&#8217;s a circuit</a> that runs through <a href="https://en.wikipedia.org/wiki/Cerebellum">cerebellum</a> that keeps the gain (ratio of head turn to eye turn) at exactly the right value. It&#8217;s a pretty clever circuit that turns out to be so useful that the brain has copy-pasted it thousands of times (with a few changes) and reused it in nearly all motor functions, plus a number of non-motor functions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PqGk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PqGk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 424w, https://substackcdn.com/image/fetch/$s_!PqGk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 848w, https://substackcdn.com/image/fetch/$s_!PqGk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 1272w, https://substackcdn.com/image/fetch/$s_!PqGk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PqGk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PqGk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 424w, https://substackcdn.com/image/fetch/$s_!PqGk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 848w, https://substackcdn.com/image/fetch/$s_!PqGk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.png 1272w, https://substackcdn.com/image/fetch/$s_!PqGk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ab80827-4a62-4c21-a8b5-29fc43dfdd2f_2160x2160.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The center of this circuit are the inhibitory Purkinje cells, which, in this case, output a low, constant stream of spikes that lightly inhibit the connections from the vestibular neurons to the motorneurons.</p><p>The vestibular signal comes in through excitatory parallel fibers that make connections with Purkinje cells. When the head turns, these fibers make the Purkinje cell a bit more excited, making it inhibit the VOR circuit a bit more, kinda like tapping on the break.</p><p>Most of the time, this inhibition is just right to make the 5&#176; head turn result in 5&#176; eye turn. But what if it&#8217;s wrong?</p><p>This is where another set of neurons comes in - the climbing fibers. When the brain detects that the image on the retina lags behind motion (i.e. the inhibition is too strong), these fire. This sets the Purkinje cell ringing like a bell for a bit, and it turns off some of the connections from the parallel fibers, reducing the inhibition, and letting the eyes move faster.</p><p>I haven&#8217;t seen a good description for how the opposite error is fixed (eyes move too fast), but from what I remember from other circuits, the parallel-to-Purkinje connections gradually turn back on when the parallel fibers keep firing, so the error may just fix itself over time.</p><h2>That&#8217;s it</h2><p>That&#8217;s basically all I know about the Vestibulo-Occular Reflex so far. As I mentioned, there are other mechanisms to keep the eyes steady, like the neck reflexes, or the slower and finer <a href="https://en.wikipedia.org/wiki/Optokinetic_response">Opto-Kinetic Reflex</a> that uses the information from the retina instead of the vestibular organ.</p>]]></content:encoded></item><item><title><![CDATA[Neuron circuits in the retina - more than just pixels]]></title><description><![CDATA[There&#8217;s also a YouTube version of this article.]]></description><link>https://www.i-kh.net/p/retina-circuits-more-than-just-pixels</link><guid isPermaLink="false">https://www.i-kh.net/p/retina-circuits-more-than-just-pixels</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Sat, 31 Oct 2020 22:37:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gcFG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gcFG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gcFG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 424w, https://substackcdn.com/image/fetch/$s_!gcFG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 848w, https://substackcdn.com/image/fetch/$s_!gcFG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 1272w, https://substackcdn.com/image/fetch/$s_!gcFG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gcFG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png" width="1296" height="1183" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1183,&quot;width&quot;:1296,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!gcFG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 424w, https://substackcdn.com/image/fetch/$s_!gcFG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 848w, https://substackcdn.com/image/fetch/$s_!gcFG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 1272w, https://substackcdn.com/image/fetch/$s_!gcFG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52689e39-3d50-45b6-9b21-e9c947cdfebf_1296x1183.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>There&#8217;s also a <a href="https://youtu.be/LMNuOn5B_VA">YouTube version</a> of this article.</em></p><p>The picture above shows some (far from everything!) of what we know about the cells and neural circuits in the human retina.</p><p>What&#8217;s interesting is - the retina is not just a light detection organ. It&#8217;s a complex electro-chemical calculator with three neural layers, and it uses these layers to extract a number of useful signals from the light that hits our eyes.</p><p>Below, we&#8217;ll step through some of the more interesting features of the retina, but if you&#8217;d like to learn more, the above picture (and this article) are mostly based on <a href="https://www.sciencedirect.com/science/article/pii/S1350946220300161">this review article</a> published in Feb 2020 in the journal Progress in Retinal and Eye Research, and on chapter 17 of the latest edition of <a href="https://www.amazon.com/Ryans-Retina-Andrew-P-Schachat/dp/032340197X">Ryan&#8217;s Retina</a>.</p><h2>Photoreceptors are always on - except when there&#8217;s light</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J2la!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J2la!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 424w, https://substackcdn.com/image/fetch/$s_!J2la!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 848w, https://substackcdn.com/image/fetch/$s_!J2la!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 1272w, https://substackcdn.com/image/fetch/$s_!J2la!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J2la!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png" width="478" height="348" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4286735f-8592-492a-ba56-c943ebe95faf_478x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:478,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!J2la!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 424w, https://substackcdn.com/image/fetch/$s_!J2la!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 848w, https://substackcdn.com/image/fetch/$s_!J2la!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.png 1272w, https://substackcdn.com/image/fetch/$s_!J2la!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4286735f-8592-492a-ba56-c943ebe95faf_478x348.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The photoreceptor cells in the vertebrate retina - rods and cones - are at the very back of the eye, behind the other layers of neurons.</p><p>Cones work best in bright light and can detect colors. In humans, there are three types of cone cells, each specializing in detecting red, green, and blue light. Rods work best in the dark, but can&#8217;t detect colors - just the brightness level.</p><p>Since the photoreceptors are at the very back of the retina, light has to navigate a tangled maze of neuronal bodies and wires to get to them. It does so using something called M&#252;ller cells (not shown), that stretch across the entire thickness of the retina and act like fiberoptic cables.</p><p>When the light gets to the photoreceptors, it turns them <em>down</em>. In complete darkness, the photoreceptors continuously emit neurotransmitters (&#8220;fire&#8221;, or &#8220;are excited&#8221;) at their maximum rate. The light inhibits them.</p><h2>Parallel channels for brightness and darkness levels</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_JTX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_JTX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 424w, https://substackcdn.com/image/fetch/$s_!_JTX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 848w, https://substackcdn.com/image/fetch/$s_!_JTX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 1272w, https://substackcdn.com/image/fetch/$s_!_JTX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_JTX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png" width="589" height="552" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:552,&quot;width&quot;:589,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!_JTX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 424w, https://substackcdn.com/image/fetch/$s_!_JTX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 848w, https://substackcdn.com/image/fetch/$s_!_JTX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.png 1272w, https://substackcdn.com/image/fetch/$s_!_JTX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8984e1a-0ec7-4cb2-acc0-6f90fc2e7625_589x552.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>For red and green cones, right from the start, the signal splits into two separate channels: ON cells, which fire neurotransmitters when the light is shining on their cone, and OFF cells that fire when the light is <em>not</em> shining on their cone.</p><p>Since the cones fire most when it&#8217;s dark, we can say that they produce the OFF (darkness) signal. So how do the ON cells fire when there&#8217;s light? Well, the ON bipolar cells are intrinsically excited and want to fire neurotransmitters, but they get inhibited by the photoreceptors. So as long as the photoreceptors are firing, ON bipolar cells aren&#8217;t. When there&#8217;s light (and photoreceptors stop firing), ON bipolar cells are no longer inhibited, and produce more neurotransmitters.</p><p>Why are there two channels instead of just one? Good question. Maybe so that it&#8217;s easier to recognize dark objects on light backgrounds more easily?</p><p>Either way, as far as we can tell, this ON/OFF channel pair only occurs with the red and green cones. Blue cones and rods have only ON bipolar cells. Though with rods, the story is a bit more complicated.</p><h2>Rod signals are carefully fed into cone pathways</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oUhr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oUhr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 424w, https://substackcdn.com/image/fetch/$s_!oUhr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 848w, https://substackcdn.com/image/fetch/$s_!oUhr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 1272w, https://substackcdn.com/image/fetch/$s_!oUhr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oUhr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png" width="680" height="571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:571,&quot;width&quot;:680,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!oUhr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 424w, https://substackcdn.com/image/fetch/$s_!oUhr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 848w, https://substackcdn.com/image/fetch/$s_!oUhr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.png 1272w, https://substackcdn.com/image/fetch/$s_!oUhr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faea0f9b1-f655-4716-b49a-c4d557efaa5a_680x571.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Humans (and other primates) have a fantastic vision. One of its crazy feats is that it can see across 10 log units of light intensity by using different light detectors and different retinal circuits in different lighting conditions.</p><p>Rods can detect single photons (!) and become saturated when it gets brighter than dusk/dawn. Rod signals are further amplified by neurons that collect multiple rod signals, suppress the noise, and feed the signals into the cone signal pathways.</p><p>This is done with help of the so-called AII amacrine cells (that&#8217;s roman numeral &#8220;2&#8221;, so it&#8217;s really &#8220;A2&#8221;, but the literature calls it &#8220;AII&#8221; for historical reasons). These AII cells collect inputs from the rod bipolar cells (which come only in ON variety), and use that signal to inhibit the cone OFF bipolar cells, as well as directly feed voltage into the ON bipolar cells through the connections called &#8220;gap junctions&#8221;.</p><p>This way, even when it&#8217;s dark, the same parts of the brain can be used to process the incoming information even though it&#8217;s been collected by a different set of photoreceptors.</p><h2>Motion gets detected starting in the retina</h2><p>Some output neurons - Parasol cells (ON and OFF varieties) and Recursive cells - produce the biggest response when the stimulus moves across its visual field.</p><p>What kind of neuron circuits make that happen?</p><p>For parasol cells, <a href="https://www.cell.com/neuron/pdf/S0896-627318%2930105-3.pdf">this paper</a> suggests that it&#8217;s a network of special diffuse bipolar cells that makes it happen.</p><p>When the signal moves left to right in the image below, the bipolar cells excite each other through gap junctions that let voltage jump from one cell to the next.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aNmg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aNmg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 424w, https://substackcdn.com/image/fetch/$s_!aNmg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 848w, https://substackcdn.com/image/fetch/$s_!aNmg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 1272w, https://substackcdn.com/image/fetch/$s_!aNmg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aNmg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png" width="541" height="602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60528b29-aef1-4801-a099-2b7f4956c315_541x602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:602,&quot;width&quot;:541,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!aNmg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 424w, https://substackcdn.com/image/fetch/$s_!aNmg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 848w, https://substackcdn.com/image/fetch/$s_!aNmg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.png 1272w, https://substackcdn.com/image/fetch/$s_!aNmg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60528b29-aef1-4801-a099-2b7f4956c315_541x602.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Due to the internal mechanisms of neurons, these signals add more than linearly and produce a big response in the last bipolar neuron - ultimately exciting the parasol cell a lot.</p><h2>Horizontal cells sharpen the picture</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lkaz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lkaz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 424w, https://substackcdn.com/image/fetch/$s_!lkaz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 848w, https://substackcdn.com/image/fetch/$s_!lkaz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 1272w, https://substackcdn.com/image/fetch/$s_!lkaz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lkaz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png" width="415" height="456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95496421-ef3a-458c-9600-027b4948e9a6_415x456.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:456,&quot;width&quot;:415,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!lkaz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 424w, https://substackcdn.com/image/fetch/$s_!lkaz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 848w, https://substackcdn.com/image/fetch/$s_!lkaz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.png 1272w, https://substackcdn.com/image/fetch/$s_!lkaz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95496421-ef3a-458c-9600-027b4948e9a6_415x456.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Retina also has a number of circuits for sharpening the image and enhancing the contrast.</p><p>One of them involves the so-called &#8220;horizontal cells&#8221; (yellow &#8220;H1&#8221; and &#8220;H2&#8221; cell in the image at the start of this post). These live in the same layer as the bipolar cells and connect to a lot of nearby cones.</p><p>The way the horizontal cells work is pretty clever: they are excited by the cones, and then, in turn, inhibit the cones back.</p><p>To see how these sharpen the image, let&#8217;s carefully look at what happens when the light shines only on one photoreceptor in the picture above.</p><p>If only one cone receives light, then</p><ol><li><p>It fires less, so</p></li><li><p>Horizontal cell is less excited, and so it fires less too, therefore</p></li><li><p>Horizontal cell doesn&#8217;t inhibit the other surrounding cones as much, and so</p></li><li><p>Other cones fire more, producing a stronger OFF (darkness) signal.</p></li></ol><p>The result is that we see a bright dot surrounded by a darker ring, making the dot more prominent.</p><p>By the way, this type of center-surround contrast enhancement is a common feature across all sensory systems, including touch, hearing, and smell.</p><p>Like image sharpening in Photoshop, this process can leave artifacts. The most famous one is below - the <a href="https://en.wikipedia.org/wiki/Grid_illusion">Hermann grid</a>. The dark spots at the intersections disappear when you look straight at them because the surround inhibition fields are larger at the periphery of vision than in the center.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G38k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G38k!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 424w, https://substackcdn.com/image/fetch/$s_!G38k!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 848w, https://substackcdn.com/image/fetch/$s_!G38k!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 1272w, https://substackcdn.com/image/fetch/$s_!G38k!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G38k!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif" width="360" height="360" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:360,&quot;width&quot;:360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!G38k!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 424w, https://substackcdn.com/image/fetch/$s_!G38k!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 848w, https://substackcdn.com/image/fetch/$s_!G38k!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 1272w, https://substackcdn.com/image/fetch/$s_!G38k!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2983003f-8451-4f16-b95c-1faba4aa6941_360x360.gif 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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Blue cones are lower-class citizens in the retina.</h2><p>For various reasons, blue cones get treated differently by the retina. They sit a bit farther back from green and red cones, they don&#8217;t get OFF channels, and there aren&#8217;t output (ganglion) cells that produce a pure blue signal.</p><p>Instead, the ganglion cells responsible for blue color combine blue ON signal together with red+green (= yellow) OFF signal to produce a &#8220;relatively blue&#8221; signal.</p><p>Blue cones are also sparser and aren&#8217;t present in the very center of the retina. This is in part because the lens in the eye produces chromatic aberrations at shorter wavelengths, and tighter spacing between blue cones wouldn&#8217;t help us see better.</p><h2>Dopamine acts as additional gain control</h2><p>Retina also adapts to light through Dopaminergic Amacrine Cells (DAC - dark blue on the diagram above). They spread their tentacles throughout the retina and around the bodies of some neurons.</p><p>When the light becomes bright enough, they ramp up the dopamine production, which in turn lowers the volume in the retinal circuits through <a href="https://www.sciencedirect.com/science/article/pii/S1347861319310448">various mecanisms</a>.</p>]]></content:encoded></item><item><title><![CDATA[How neurons create electric spikes]]></title><description><![CDATA[And here&#8217;s the same content as the last blog post, but now in YouTube format.]]></description><link>https://www.i-kh.net/p/how-neurons-make-electric-spikes</link><guid isPermaLink="false">https://www.i-kh.net/p/how-neurons-make-electric-spikes</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Tue, 15 Sep 2020 23:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/gPjT1O-4DLU" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>And here&#8217;s the same content as the last blog post, but now in YouTube format.</p><div id="youtube2-gPjT1O-4DLU" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;gPjT1O-4DLU&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/gPjT1O-4DLU?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div>]]></content:encoded></item><item><title><![CDATA[Multithreading without locks]]></title><description><![CDATA[Just because you&#8217;re sharing data structures between threads doesn&#8217;t mean you have to use locks.]]></description><link>https://www.i-kh.net/p/multithreading-without-locks</link><guid isPermaLink="false">https://www.i-kh.net/p/multithreading-without-locks</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 10 Feb 2020 23:03:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!V9Qv!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64d2997e-d235-41e8-8ece-611b5f6c9f21_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Just because you&#8217;re sharing data structures between threads doesn&#8217;t mean you have to use locks.</p><p>Over the years I&#8217;ve come across a few approaches that help coordinate work between threads without having to make anyone wait. Here are a couple of them.</p><p>WARNING: I stopped using these patterns because they are easy to misunderstand and misuse, which can lead to random hard-to-diagnose bugs. If you use these patterns, you&#8217;re not helping the next develper understand the code better or avoid mistakes. You have been warned.</p><h2>Reference to an immutable object</h2><p>We know that in a multithreaded environment, modifying a shared object without locks is a bad idea. But what about replacing it?</p><p>For example, consider this code. I&#8217;ll use C#, but the same applies in Java, C++, or another traditional language with threads.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;csharp&quot;,&quot;nodeId&quot;:&quot;bb7ea492-9b0c-44a1-8cf5-2f122da94a65&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-csharp">public class FunWithThreads {
    private Thing thing;

    public void InThreadOne() {
        this.thing = new Thing()
    }

    public Result InThreadTwo() {
        var localThing = this.thing;
        var result1 = SomeCalculation1(localThing);
        var result2 = SomeCalculation2(localThing);
        var finalResult = DoMoreWork(localThing, result1, result2);
        return result;
    }
}</code></pre></div><p>Suppose lots of threads are concurrently calling <code>InThreadOne()</code>, while lots of other threads are concurrently calling <code>InThreadTwo()</code>. Will we ever get a wrong result, a race condition, or a conflict?</p><p>Not really. <code>InThreadTwo()</code> always refers to a consistent version of <code>this.thing</code> because it places the reference to it into a local variable, and from then on uses only the local reference. If the calculations take too long, then maybe we get a result that&#8217;s a bit stale, but that result will always be consistent.</p><p><strong>Where it&#8217;s useful</strong>: I found this approach to be useful whenever <code>this.thing</code> is a large, pre-computed data structure that gets infrequently updated but frequently read. Mostly I&#8217;ve used it to cache some data for internal capital markets applications to make the application feel snappier to the user.</p><p><strong>The pitfalls</strong>: It&#8217;s really important to make sure that <code>this.thing</code> is referenced only once at the beginning of the method, or else we&#8217;re back to race conditions. It&#8217;s also really important that <code>this.thing</code> is never modified after it&#8217;s assigned. That means lots of descriptive comments, very careful code reviews, and making sure that every developer that ever looks at this code knows all the gotchas. In a larger codebase, someone (maybe even you!) might still find a way to make a mistake somewhere.</p><h2>Complex atomic operations</h2><p>The reason the above code works is because in C# (and in most other languages) assignment of references is an atomic operation, i.e. while it&#8217;s executing, another thread can&#8217;t sneak in mid-way and do something else.</p><p>Modern processors have a few other interesting atomic operations, like <a href="https://en.wikipedia.org/wiki/Compare-and-swap">compare and swap</a>, implemented in C# as <code>Interlocked.CompareExchange()</code>, and in Java as <code>AtomicInteger.compareAndSet()</code>. This function takes three arguments and does the following as an atomic operation:</p><ol><li><p>Compares the first and the third arguments, then</p></li><li><p>If they&#8217;re equal, sets the first argument to be equal to the second argument, or</p></li><li><p>If they&#8217;re not equal, does nothing.</p></li></ol><p>One case where this can be used is when trying to limit requests for an expensive operation on a limited resource. For example, this code will drop any requests if the expensive operation is already running:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;csharp&quot;,&quot;nodeId&quot;:&quot;4dbb8d84-32e6-4c7c-bf45-59c22f72287b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-csharp">// Let&#8217;s pretend this class is a singleton.
public class ExpensiveOperationLimiter {
    private int isProcessing = 0; 

    public void RequestExpensiveOperation() {
        // If isProcessing == 1, this does nothing and returns 1.
        // If isProcessing == 0, this sets isProcessing to 1 and returns 0. 
        var wasProcessing = Interlocked.CompareExchange(ref isProcessing, 1, 0);

        if (!wasProcessing) {
            // Only one invocation will be running at a time.
            DoExpensiveOperation()
        }

        isProcessing = 0;
    }

    private void DoExpensiveOperation() {
        // ...
    }
}</code></pre></div><p>If you look at the above code carefully, you&#8217;ll see that you can&#8217;t replace <code>Interlocked.CompareExchange()</code> and still have thread safety - there will always be an opportunity for another thread to sneak in between the instructions.</p><p>With a bit of work, this code can also be expanded to queue up the next request.</p><p><strong>Where it&#8217;s useful</strong>: I&#8217;ve used this kind of code in situations where events can randomly trigger an application server&#8217;s cache to refresh from a database or from another system.</p><p><strong>The pitfalls</strong>: Generally, I&#8217;d consider this to be a micro-optimization and not worth the effort. Many developers understand or have heard of locks, and have an easier time following them than any code that involves compare-and-set. As before, by using this, you&#8217;re risking someone (including you!) eventually making a mistake.</p><h2>The best way to avoid locks</h2><p>Don&#8217;t write multithreaded code!</p>]]></content:encoded></item><item><title><![CDATA[The magic of ion channels in the neurons]]></title><description><![CDATA[A few weeks ago, for various reasons I decided to start reading a neuroscience textbook (Fundamental Neuroscience).]]></description><link>https://www.i-kh.net/p/the-magic-of-ion-channels</link><guid isPermaLink="false">https://www.i-kh.net/p/the-magic-of-ion-channels</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Mon, 10 Feb 2020 23:03:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!B6RQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A few weeks ago, for various reasons I decided to start reading a neuroscience textbook (<a href="https://www.sciencedirect.com/book/9780123858702/fundamental-neuroscience">Fundamental Neuroscience</a>). Though dense, it&#8217;s packed with interesting information that filled a lot of gaps in my knowledge about the brain.</p><p>One of those gaps was about how exactly the information travels through a neuron. Up to this point, all I knew was &#8220;something involving electric pulses&#8221;.</p><p>The reality, it turns out, is more interesting: neurons use ion channels to create and strengthen electric signals, and propagate information along their lengths.</p><p>So here is more or less how I understand this so far.</p><h2>The setup - the neuron</h2><p>First, a quick recap of the neuron structure.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B6RQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B6RQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!B6RQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!B6RQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!B6RQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B6RQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A typical neuron. Source: your brain.&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 typical neuron. Source: your brain." title="A typical neuron. Source: your brain." srcset="https://substackcdn.com/image/fetch/$s_!B6RQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!B6RQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!B6RQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!B6RQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c89b3e1-f3e6-43ab-93c8-0556a1aa450c_1920x1080.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A typical neuron. Source: your brain.</figcaption></figure></div><p>A neuron has the main cell body. From that body, it grows a large number of branched extensions called &#8220;dendrites&#8221;. These usually serve as the input &#8220;wires&#8221;, though they also do some signal processing.</p><p>Neuron usually also grows another long extension called an &#8220;axon&#8221;. This is normally the cell&#8217;s output, and it can be up to a meter long in humans, though in the brain it&#8217;s usually shorter.</p><p>Let&#8217;s zoom in to the axon. First, we&#8217;ll look at shorter axons, because longer ones have myelin sheath, which will complicate the picture.</p><h2>Ions provide the electric charge</h2><p>The fluid inside the neuron (cytoplasm) and the intercellular fluid between the neurons have a number of ions dissolved in them: calcium (Ca&#178;&#8314;), potassium (K&#8314;), sodium (Na&#8314;), chlorine (Cl&#8315;), and others.</p><p>For various reasons, neurons actively work to pump out Na&#8314;, Ca&#178;&#8314;, and Cl&#8315;, so these are much more concentrated outside the cell than inside the cell. If the membrane wasn&#8217;t keeping them out, they&#8217;d quickly rush into the cell. Some still leak back in.</p><p>Similarly, neurons actively work to concentrate K&#8314; inside.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d4Sg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d4Sg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!d4Sg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!d4Sg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!d4Sg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d4Sg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A crude depiction of a Na&#8314;-K&#8314; pump, one of the mechanisms maintaining the ion balance in the neuron. Na&#8314;-K&#8314; pump removes three Na&#8314; ions for two K&#8314; ions.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A crude depiction of a Na&#8314;-K&#8314; pump, one of the mechanisms maintaining the ion balance in the neuron. Na&#8314;-K&#8314; pump removes three Na&#8314; ions for two K&#8314; ions." title="A crude depiction of a Na&#8314;-K&#8314; pump, one of the mechanisms maintaining the ion balance in the neuron. Na&#8314;-K&#8314; pump removes three Na&#8314; ions for two K&#8314; ions." srcset="https://substackcdn.com/image/fetch/$s_!d4Sg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!d4Sg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!d4Sg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!d4Sg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff90d1b16-752e-4bfb-b8f4-0b84c2049da3_1920x1080.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A crude depiction of a Na&#8314;-K&#8314; pump, one of the mechanisms maintaining the ion balance in the neuron. Na&#8314;-K&#8314; pump removes three Na&#8314; ions for two K&#8314; ions.</figcaption></figure></div><p>Each of the ions carries a charge, so the end result of this pumping is that the cell&#8217;s inside is negatively charged relative to the outside. This voltage difference is called the &#8220;membrane potential&#8221;. Resting membrane potential is typically between -75 and -40 mV (millivolts).</p><h2>Ion channels create voltage spikes</h2><p>Ion channels are small valves set in the cell&#8217;s surface that let ions through if certain conditions are met. Some are opened by specific chemicals binding to them (e.g. neurotransmitters), while others open when the voltage inside the cell rises high enough. The latter are called &#8220;voltage-gated ion channels&#8221;, and they&#8217;re the ones we&#8217;re interested in.</p><p>Voltage-gated ion channels exist on all parts of a neuron, but are most concentrated in the axon. Most let through a specific ion: there are Na&#8314; channels, K&#8314; channels, Ca&#178;&#8314; channels, etc.</p><p>Let&#8217;s take a look at how Na&#8314; channels and K&#8314; channels would work to produce a voltage spike (called an &#8220;action potential&#8221;).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HxwR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HxwR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!HxwR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!HxwR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!HxwR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HxwR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/05561557-b552-441c-a733-b00e46e35961_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Neuron membrane in resting state. Channels are closed; membrane voltage is around -73 mV.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Neuron membrane in resting state. Channels are closed; membrane voltage is around -73 mV." title="Neuron membrane in resting state. Channels are closed; membrane voltage is around -73 mV." srcset="https://substackcdn.com/image/fetch/$s_!HxwR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!HxwR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!HxwR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!HxwR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05561557-b552-441c-a733-b00e46e35961_1920x1080.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Neuron membrane in resting state. Channels are closed; membrane voltage is around -73 mV.</figcaption></figure></div><p>If something increases the cell membrane voltage to -55 mV, Na&#8314; channels quickly open and let in a lot of Na&#8314; ions. These ions carry a positive charge, so they quickly raise the voltage across the membrane to +30 mV. Then the channels automatically close. This happens over the span of milliseconds.</p><p>At the same time, K&#8314; channels open and start letting out some K&#8314; ions, opposing the Na&#8314; current and slowing the voltage increase. The channels first open slowly, but after a while, the K&#8314; current strengthens.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R1f5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R1f5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!R1f5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!R1f5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!R1f5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!R1f5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Voltage spikes up after the channels open. Na&#8314; are flowing quickly, and K&#8314; are flowing slowly. Na&#8314; channel is about to close.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Voltage spikes up after the channels open. Na&#8314; are flowing quickly, and K&#8314; are flowing slowly. Na&#8314; channel is about to close." title="Voltage spikes up after the channels open. Na&#8314; are flowing quickly, and K&#8314; are flowing slowly. Na&#8314; channel is about to close." srcset="https://substackcdn.com/image/fetch/$s_!R1f5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!R1f5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!R1f5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!R1f5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46b3a191-6f1b-4c72-b88b-fb431c7f6a41_1920x1080.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Voltage spikes up after the channels open. Na&#8314; are flowing quickly, and K&#8314; are flowing slowly. Na&#8314; channel is about to close.</figcaption></figure></div><p>To start, Na+ channels dominate, but after they close, K&#8314; outflow quickly makes the membrane voltage drop. This drop overshoots the initial resting level before leveling off at the voltage where K&#8314; concentrations stay stable.</p><p>Then K&#8314; channels gradually close.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!52iq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!52iq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!52iq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!52iq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!52iq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!52iq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot; Na&#8314; channel is closed. K&#8314; has concentrations have leveled off around -73 mV, where K&#8314; ions are equally likely to enter and exit the membrane.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt=" Na&#8314; channel is closed. K&#8314; has concentrations have leveled off around -73 mV, where K&#8314; ions are equally likely to enter and exit the membrane." title=" Na&#8314; channel is closed. K&#8314; has concentrations have leveled off around -73 mV, where K&#8314; ions are equally likely to enter and exit the membrane." srcset="https://substackcdn.com/image/fetch/$s_!52iq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!52iq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!52iq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!52iq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c01caf1-c622-49c2-b1b8-ef94596a977d_1920x1080.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Na&#8314; channel is closed. K&#8314; has concentrations have leveled off around -73 mV, where K&#8314; ions are equally likely to enter and exit the membrane.</figcaption></figure></div><p>The total number of ions exchanged throughout the whole process is minuscule, and has little impact on the overall concentration of ions inside or outside the cell.</p><h2>Voltage spike opens nearby channels</h2><p>When the channels create a voltage spike, they then trigger other nearby channels, which then trigger other channels, and so on. This makes the voltage spike travel down the length of the neuron.</p><p>The ion channels usually take time to reset before the next firing, so a single voltage spike doesn&#8217;t usually set off the entire neuron ringing indefinitely. However, the voltage can propagate from the base of the axon back into the dendrites, where it can play an important role in influencing whether the next incoming signal will set off the ion channels there.</p><h2>Membrane properties limit the signal speed</h2><p>Neurons are somewhat conductive, but not <em>very</em> conductive - they&#8217;re not copper wires. They&#8217;re also leaky - a large portion of their current seeps out into the surrounding intercellular fluid, partly because the cell membrane is not 100% impermeable to ions, and partly because of the membrane capacitance.</p><p>That means that if a given ion channel generates some voltage locally, that voltage will quickly drop off as we move farther from that channel.</p><p>So the ion channels cannot be spaced too far apart, and the signal will travel only as fast as the channels can open and close between the start and the end of the axon.</p><h2>Myelin speeds up the signal</h2><p>Vertebrates (including humans) have a clever innovation to speed up the propagation of signals: they use myelin sheaths to insulate axons that travel over distances longer than millimeters.</p><p>Myelin sheaths surrounding an axon of the peripheral nervous system (i.e. outside the brain or spine). Source: &#8220;Anatomy and Physiology&#8221; by the US National Cancer Institute&#8217;s Surveillance, Epidemiology and End Results (SEER) Program.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OX3r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OX3r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 424w, https://substackcdn.com/image/fetch/$s_!OX3r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 848w, https://substackcdn.com/image/fetch/$s_!OX3r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 1272w, https://substackcdn.com/image/fetch/$s_!OX3r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OX3r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg" width="1456" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Myelin sheaths surrounding an axon of the peripheral nervous system (i.e. outside the brain or spine). Source: \&quot;Anatomy and Physiology\&quot; by the US National Cancer Institute's Surveillance, Epidemiology and End Results (SEER) Program.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Myelin sheaths surrounding an axon of the peripheral nervous system (i.e. outside the brain or spine). Source: &quot;Anatomy and Physiology&quot; by the US National Cancer Institute's Surveillance, Epidemiology and End Results (SEER) Program." title="Myelin sheaths surrounding an axon of the peripheral nervous system (i.e. outside the brain or spine). Source: &quot;Anatomy and Physiology&quot; by the US National Cancer Institute's Surveillance, Epidemiology and End Results (SEER) Program." srcset="https://substackcdn.com/image/fetch/$s_!OX3r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 424w, https://substackcdn.com/image/fetch/$s_!OX3r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 848w, https://substackcdn.com/image/fetch/$s_!OX3r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 1272w, https://substackcdn.com/image/fetch/$s_!OX3r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09eedbc7-5c9b-4854-b74a-394d40d53e2b.svg 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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Myelin sheaths surrounding an axon of the peripheral nervous system (i.e. outside the brain or spine). Source: "Anatomy and Physiology" by the US National Cancer Institute's Surveillance, Epidemiology and End Results (SEER) Program.</figcaption></figure></div><p>Myelin sheaths form in 0.2- 1 mm segments over the neurons and are made from layers of cell membrane and protein made by the dedicated cells - oligodendrocytes in the brain and spinal cord, and by Schwann cells everywhere else.</p><p>Myelin significantly thickens the axon&#8217;s wall and reduces the amount of current leaked out through the cell membrane. This allows the myelinated neuron to space their ion channels farther apart, significantly speeding up the propagation of the voltage spikes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!igMe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!igMe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!igMe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!igMe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!igMe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!igMe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!igMe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!igMe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!igMe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!igMe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa7e31db3-6a85-4e27-ae85-cdf5c03a0bda_1920x1080.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 buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div>]]></content:encoded></item><item><title><![CDATA[Newcomen atmospheric engine - an animation]]></title><description><![CDATA[A stylized animation of Newcomen engine that I made a while back.]]></description><link>https://www.i-kh.net/p/newcomen-engine</link><guid isPermaLink="false">https://www.i-kh.net/p/newcomen-engine</guid><dc:creator><![CDATA[Iouri Khramtsov]]></dc:creator><pubDate>Sat, 08 Feb 2020 22:06:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ugmo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A stylized animation of <a href="https://en.wikipedia.org/wiki/Newcomen_atmospheric_engine">Newcomen engine</a> that I made a while back.</p><p>Newcomen engine is one of the first viable steam engines originally made in 1712 in England to pump water out of mines.</p><p>Unlike later steam engines, it was an &#8220;atmospheric engine&#8221; in which the power stroke was produced by the steam condensing into water and thus creating a vacuum; the atmospheric pressure then pushed the cylinder down, moving the big beam.</p><p>It was extremely inefficient by modern standards, but that wasn&#8217;t a big deal if it was sitting next to a coal mine.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;affa3329-d95f-4b6b-af74-c91bd9d58b0e&quot;,&quot;duration&quot;:null}"></div><h2>Some fun details</h2><ul><li><p>This engine is shown pumping the water out of a mine. The bulk of this water was discarded, but some was pumped up to a container at the top that would feed the engine.</p></li><li><p>If too much air got into the main cylinder, it would stall. That&#8217;s why you see the engine leaking a bit of steam through a pipe when it&#8217;s inflating - to make sure that there&#8217;s minimum air in the main cylinder. The valve that the steam is leaking from was called the &#8220;snifting valve&#8221;.</p></li><li><p>The big vertical plank that moves up and down is called the &#8220;plug tree&#8221;.</p></li><li><p>The little stream of water on top of the cylinder is there to create an airtight seal.</p></li><li><p>Fire is really painful to animate by hand if you don&#8217;t have any animation experience.</p></li></ul><p>Not shown in the animation is an avanced feature of some of the engines: a pressure-controlled valve that helped refill the water in the boiler.</p><p>The animation above is rather stylized. This sketch from a 1868 book shows what it actually looked like on the inside:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ugmo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ugmo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ugmo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ugmo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ugmo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ugmo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg" width="1354" height="1369" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1369,&quot;width&quot;:1354,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A sketch from Louis Figuer's 1868 book \&quot;Merveilles de la science\&quot;.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A sketch from Louis Figuer's 1868 book &quot;Merveilles de la science&quot;." title="A sketch from Louis Figuer's 1868 book &quot;Merveilles de la science&quot;." srcset="https://substackcdn.com/image/fetch/$s_!ugmo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ugmo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ugmo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ugmo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29c17428-d743-411c-97f0-979cd25191a5_1354x1369.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A sketch from Louis Figuer's 1868 book "Merveilles de la science".</figcaption></figure></div><p>Though typically the boiler, the pipes, and the switches would be enclosed in a brick structure like the one below. You can see the same engine in action in <a href="https://www.youtube.com/watch?v=HC6LUWSBXjk">this YouTube video</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZufQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZufQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ZufQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ZufQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ZufQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZufQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg" width="1280" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A replica of a Newcomen engine at the Black Country Museum in the UK. Source: Wikimedia Commons.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A replica of a Newcomen engine at the Black Country Museum in the UK. Source: Wikimedia Commons." title="A replica of a Newcomen engine at the Black Country Museum in the UK. Source: Wikimedia Commons." srcset="https://substackcdn.com/image/fetch/$s_!ZufQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ZufQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ZufQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ZufQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffab97fd4-5f8b-461b-b2f8-65d5a442f76e_1280x859.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A replica of a Newcomen engine at the Black Country Museum in the UK. Source: Wikimedia Commons.</figcaption></figure></div>]]></content:encoded></item></channel></rss>