<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="https://will-keleher.com/" rel="self" type="application/rss+xml" />
    <title>will-keleher.com</title>
    <link>https://will-keleher.com/</link>
    <description>I don&#39;t think I can build a fence with these posts...</description>
    <item>
      <title>Telling a Computer to Do Things</title>
      <link>https://will-keleher.com/posts/telling-your-computer-to-do-things/</link>
      <guid>https://will-keleher.com/posts/telling-your-computer-to-do-things/</guid>
      <pubDate>Thu, 16 Apr 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Knowing the shell lets you tell a computer how to do things.]]></description>
    </item>
    <item>
      <title>Don&#39;t Forget to Set EDITOR and VISUAL</title>
      <link>https://will-keleher.com/posts/dont-forget-to-set-editor-and-visual/</link>
      <guid>https://will-keleher.com/posts/dont-forget-to-set-editor-and-visual/</guid>
      <pubDate>Wed, 15 Apr 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Unless you actually use `vim`, you'll likely want to set both EDITOR and VISUAL to whatever code editor you actually like to use!]]></description>
          <media:content url="https://will-keleher.com/posts/dont-forget-to-set-editor-and-visual/preview.png" medium="image" />
    </item>
    <item>
      <title>The Post-mortem Spectrum</title>
      <link>https://will-keleher.com/posts/the-post-mortem-spectrum/</link>
      <guid>https://will-keleher.com/posts/the-post-mortem-spectrum/</guid>
      <pubDate>Fri, 10 Apr 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[If you only ever do 'big' post-mortems for gigantic outages, you'll miss good opportunities to learn and improve your systems.]]></description>
    </item>
    <item>
      <title>Small Programming Tricks</title>
      <link>https://will-keleher.com/posts/small-programming-tricks-matter/</link>
      <guid>https://will-keleher.com/posts/small-programming-tricks-matter/</guid>
      <pubDate>Thu, 19 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[A lot of effective engineering comes from the accumulation of small nuggets of knowledge.]]></description>
    </item>
    <item>
      <title>You&#39;re already running canary servers</title>
      <link>https://will-keleher.com/posts/nary-an-error-with-canary/</link>
      <guid>https://will-keleher.com/posts/nary-an-error-with-canary/</guid>
      <pubDate>Wed, 18 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[You're already running canary servers – servers that validate new code against production traffic – but they might just be called "prod."]]></description>
          <media:content url="https://will-keleher.com/posts/nary-an-error-with-canary/preview.png" medium="image" />
    </item>
    <item>
      <title>and these screenshots prove I did it</title>
      <link>https://will-keleher.com/posts/and-these-screenshots-prove-i-did-it/</link>
      <guid>https://will-keleher.com/posts/and-these-screenshots-prove-i-did-it/</guid>
      <pubDate>Mon, 16 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[]]></description>
          <media:content url="https://will-keleher.com/posts/and-these-screenshots-prove-i-did-it/preview.png" medium="image" />
    </item>
    <item>
      <title>this css proves me human</title>
      <link>https://will-keleher.com/posts/this-css-makes-me-human/</link>
      <guid>https://will-keleher.com/posts/this-css-makes-me-human/</guid>
      <pubDate>Fri, 06 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[]]></description>
          <media:content url="https://will-keleher.com/posts/this-css-makes-me-human/preview.png" medium="image" />
    </item>
    <item>
      <title>Ratcheting SQL Queries: reducing a database&#39;s load by 1/4th with a simple change</title>
      <link>https://will-keleher.com/posts/ratcheting-sql-queries/</link>
      <guid>https://will-keleher.com/posts/ratcheting-sql-queries/</guid>
      <pubDate>Thu, 05 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Query planners aren't perfect. Ratcheting SQL queries can sometimes dramatically reduce load.]]></description>
    </item>
    <item>
      <title>Script Your Code Migrations</title>
      <link>https://will-keleher.com/posts/script-your-code-migrations/</link>
      <guid>https://will-keleher.com/posts/script-your-code-migrations/</guid>
      <pubDate>Thu, 05 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Writing programs to modify code should be a regular part of every engineer's toolkit.]]></description>
          <media:content url="https://will-keleher.com/posts/script-your-code-migrations/preview.png" medium="image" />
    </item>
    <item>
      <title>An Elegy for my Beloved Slow Query Logs</title>
      <link>https://will-keleher.com/posts/augment-your-slow-query-logs/</link>
      <guid>https://will-keleher.com/posts/augment-your-slow-query-logs/</guid>
      <pubDate>Wed, 04 Mar 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Slow query logs that include the request that caused them, a name that ties them back to the exact location the query comes from, and basic info about the requesting client make improving database performance easy.]]></description>
    </item>
    <item>
      <title>Store Every Request</title>
      <link>https://will-keleher.com/posts/store-every-request/</link>
      <guid>https://will-keleher.com/posts/store-every-request/</guid>
      <pubDate>Fri, 27 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[A record of every request that hits your backend is useful for debugging and analysis. Let's chat through the details.]]></description>
    </item>
    <item>
      <title>More Shell Patterns I Use Weekly</title>
      <link>https://will-keleher.com/posts/more-shell-patterns-i-use-weekly/</link>
      <guid>https://will-keleher.com/posts/more-shell-patterns-i-use-weekly/</guid>
      <pubDate>Fri, 27 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[A few quick notes on string parameter expansion (`${file/.md/.html}`), adding colors to `printf`, `/tmp` and `mktemp`, and using `awk` for filtering]]></description>
    </item>
    <item>
      <title>Nano Banana 2 Partially Passes the Seven-legged Spider Test</title>
      <link>https://will-keleher.com/posts/nano-banana-2-partially-passes-the-spider-test/</link>
      <guid>https://will-keleher.com/posts/nano-banana-2-partially-passes-the-spider-test/</guid>
      <pubDate>Thu, 26 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Nano Banana 2 still can't create a seven-legged spider, but the Gemini model at least realizes that it's failed.]]></description>
    </item>
    <item>
      <title>(Almost) Every table needs `request_uuid`</title>
      <link>https://will-keleher.com/posts/you-should-store-request_uuids-in-tables/</link>
      <guid>https://will-keleher.com/posts/you-should-store-request_uuids-in-tables/</guid>
      <pubDate>Wed, 25 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Every table needs audit information. Rather than storing columns like `created_by`, `updated_by`, and `updated_at`, I instead prefer to store a `latest_request_uuid` column to tie mutations back to specific user's request.]]></description>
    </item>
    <item>
      <title>CSS Tweaks for This Site That Make Me Happy</title>
      <link>https://will-keleher.com/posts/css-tweaks-for-this-blog-that-make-me-happy/</link>
      <guid>https://will-keleher.com/posts/css-tweaks-for-this-blog-that-make-me-happy/</guid>
      <pubDate>Tue, 24 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[@view-transitions, ::after pseudo elements, counter(), and a few more small techniques that I was happy to discover when building things for this site.]]></description>
    </item>
    <item>
      <title>Literal and Optional Parameters Can Make Code Hard to Read (in TypeScript)</title>
      <link>https://will-keleher.com/posts/i-hate-literal-arguments/</link>
      <guid>https://will-keleher.com/posts/i-hate-literal-arguments/</guid>
      <pubDate>Thu, 12 Feb 2026 21:11:40 &#43;0000</pubDate>
      <description><![CDATA[Avoiding literal and optional parameters leads to more readable code, and you should consider turning inlay hints for literal parameter names on if your editor supports them.]]></description>
    </item>
    <item>
      <title>How I Review LLM-generated Code</title>
      <link>https://will-keleher.com/posts/reviewing-llm-generated-code/</link>
      <guid>https://will-keleher.com/posts/reviewing-llm-generated-code/</guid>
      <pubDate>Thu, 05 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Code review is essential for getting value out of AI-generated code, which makes trunk-based development, a good diff viewer, LLM review, and opening code locally crucial]]></description>
    </item>
    <item>
      <title>It&#39;s 2026, and I&#39;m still leery of using LLMs to generate code</title>
      <link>https://will-keleher.com/posts/leery-of-using-ai-to-generate-code/</link>
      <guid>https://will-keleher.com/posts/leery-of-using-ai-to-generate-code/</guid>
      <pubDate>Wed, 04 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[LLMs are great at generating code, but writing code helps me think and understand the system I'm building.]]></description>
    </item>
    <item>
      <title>You probably don&#39;t need `find`</title>
      <link>https://will-keleher.com/posts/you-probably-dont-need-find/</link>
      <guid>https://will-keleher.com/posts/you-probably-dont-need-find/</guid>
      <pubDate>Wed, 04 Feb 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Between zsh's globbing, Bash's `shopt -s globstar`, and `fd`, you probably can avoid ever using `find`.]]></description>
          <media:content url="https://will-keleher.com/posts/you-probably-dont-need-find/preview.png" medium="image" />
    </item>
    <item>
      <title>Three Technical Tricks for Non-technical Writers in Google Docs</title>
      <link>https://will-keleher.com/posts/three-technical-tricks-for-non-technical-writers/</link>
      <guid>https://will-keleher.com/posts/three-technical-tricks-for-non-technical-writers/</guid>
      <pubDate>Fri, 30 Jan 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Regular expressions with word boundaries, pasting without formatting,  and markdown format can occasionally save non-technical writers a teeny bit of work.]]></description>
          <media:content url="https://will-keleher.com/images/find-and-replace.png" medium="image" />
    </item>
    <item>
      <title>Useless shell commands</title>
      <link>https://will-keleher.com/posts/useless-shell-commands/</link>
      <guid>https://will-keleher.com/posts/useless-shell-commands/</guid>
      <pubDate>Wed, 28 Jan 2026 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Detailed instructions to fix `echo`, abuse HEREDOCs, and use `say` in pipelines.]]></description>
          <media:content url="https://will-keleher.com/images/previews/true_echo.png" medium="image" />
    </item>
    <item>
      <title>Why doesn&#39;t MySQL&#39;s query planner rewrite some `ORDER BY.. LIMIT` queries to use a `UNION` strategy? No clue.</title>
      <link>https://will-keleher.com/posts/mysql-degenerate-query-plan/</link>
      <guid>https://will-keleher.com/posts/mysql-degenerate-query-plan/</guid>
      <pubDate>Sat, 22 Nov 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[I'm surprised that MySQL isn't able to come up with a better query plan for queries like `SELECT * FROM X WHERE Y in (a, b) ORDER BY Z LIMIT 10` when there's an index on `(Y, Z)`. What the heck, MySQL?]]></description>
          <media:content url="https://will-keleher.com/preview.png" medium="image" />
    </item>
    <item>
      <title>A one-table SQL query will often use a single index</title>
      <link>https://will-keleher.com/posts/sql-queries-rarely-use-multiple-indexes/</link>
      <guid>https://will-keleher.com/posts/sql-queries-rarely-use-multiple-indexes/</guid>
      <pubDate>Wed, 08 Oct 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[For a query like `WHERE A = ? AND B = ?`, the most efficient index will be on `(A, B)` or `(B, A)`. Two indexes on `(A)` and `(B)` won't necessarily be combined.]]></description>
          <media:content url="https://will-keleher.com/posts/sql-queries-rarely-use-multiple-indexes/preview.png" medium="image" />
    </item>
    <item>
      <title>You should lint your TODOs</title>
      <link>https://will-keleher.com/posts/you-should-lint-your-todos/</link>
      <guid>https://will-keleher.com/posts/you-should-lint-your-todos/</guid>
      <pubDate>Mon, 22 Sep 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[TODOs are more useful when they have a consistent format! You should decide on what types of TODOs you want to allow in your codebase and make sure they follow a consistent format that you can use for searches and scripts.]]></description>
          <media:content url="https://will-keleher.com/posts/you-should-lint-your-todos/preview.png" medium="image" />
    </item>
    <item>
      <title>You probably want some parts of Lodash</title>
      <link>https://will-keleher.com/posts/you-probably-want-lodash/</link>
      <guid>https://will-keleher.com/posts/you-probably-want-lodash/</guid>
      <pubDate>Sun, 21 Sep 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[A good chunk of the coding I've done has been munging data into appropriate shapes. It's nice to have useful helper functions that make it easier to change shapes around, and I think Lodash contains a good set of key utility functions to do that well.]]></description>
          <media:content url="https://will-keleher.com/posts/you-probably-want-lodash/preview.png" medium="image" />
    </item>
    <item>
      <title>Draw a Silhouette of a Spider Missing its Front Left Leg</title>
      <link>https://will-keleher.com/posts/draw-a-silhouette-of-a-spider-missing-its-front-left-leg/</link>
      <guid>https://will-keleher.com/posts/draw-a-silhouette-of-a-spider-missing-its-front-left-leg/</guid>
      <pubDate>Tue, 24 Jun 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[I found it striking how incapable every AI model I tried was of drawing a spider silhouette missing one leg.]]></description>
          <media:content url="https://will-keleher.com/images/spiders/gemini-screenshot.png" medium="image" />
    </item>
    <item>
      <title>Don&#39;t lecture when teaching software engineering</title>
      <link>https://will-keleher.com/posts/how-to-create-effective-learning-materials-at-engineering-orgs/</link>
      <guid>https://will-keleher.com/posts/how-to-create-effective-learning-materials-at-engineering-orgs/</guid>
      <pubDate>Fri, 04 Apr 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[The basics of good pedagogy—starting with learning goals and incorporating lots of practice—can improve internal company engineer training.]]></description>
          <media:content url="https://will-keleher.com/posts/how-to-create-effective-learning-materials-at-engineering-orgs/preview.png" medium="image" />
    </item>
    <item>
      <title>I avoid easy things I haven&#39;t tried</title>
      <link>https://will-keleher.com/posts/i-avoid-easy-things-i-havent-tried/</link>
      <guid>https://will-keleher.com/posts/i-avoid-easy-things-i-havent-tried/</guid>
      <pubDate>Thu, 03 Apr 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[When I haven't tried something, it ends up being a huge barrier towards adding that tool to my toolbox. It took me _years_ to spend 2 minutes figuring out how to record my screen.]]></description>
    </item>
    <item>
      <title>Why I avoid test stubs in TypeScript</title>
      <link>https://will-keleher.com/posts/why-i-dislike-stubs/</link>
      <guid>https://will-keleher.com/posts/why-i-dislike-stubs/</guid>
      <pubDate>Tue, 01 Apr 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Stubs that mutate objects are hard to maintain and can cause hard-to-debug problems for future engineers. I use "explicit stubbing" and build general test utilities whenever I need stubbing behavior.]]></description>
          <media:content url="https://will-keleher.com/posts/why-i-dislike-stubs/preview.png" medium="image" />
    </item>
    <item>
      <title>Most engineers have git aliases; what are yours?</title>
      <link>https://will-keleher.com/posts/what-are-your-git-aliases/</link>
      <guid>https://will-keleher.com/posts/what-are-your-git-aliases/</guid>
      <pubDate>Wed, 26 Mar 2025 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Git is flexible and powerful, but it takes a lot of commands to do most workflows. Most engineers I know have their own custom set of git aliases to simplify those commands. What are yours?]]></description>
          <media:content url="https://will-keleher.com/images/previews/git_aliases.png" medium="image" />
    </item>
    <item>
      <title>When helping elves, you should use complex numbers to navigate in 2D</title>
      <link>https://will-keleher.com/posts/2d-navigation-with-imaginary-numbers-is-better/</link>
      <guid>https://will-keleher.com/posts/2d-navigation-with-imaginary-numbers-is-better/</guid>
      <pubDate>Sat, 21 Dec 2024 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Complex numbers can represent vectors in Python in a way that arrays or tuples can't, and they lead to more natural way of structuring 2D data.]]></description>
          <media:content url="https://will-keleher.com/images/previews/imaginary_numbers.png" medium="image" />
    </item>
    <item>
      <title>18,957 tests in under 6 minutes: ClassDojo&#39;s approach to backend testing</title>
      <link>https://will-keleher.com/posts/classdojos-approach-to-backend-testing/</link>
      <guid>https://will-keleher.com/posts/classdojos-approach-to-backend-testing/</guid>
      <pubDate>Fri, 13 Dec 2024 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[When writing backend tests, the database is an integral part of what we'd like to test. Putting effort into test & fixture resetting speed can make tests that hit the database possible.]]></description>
          <media:content url="https://will-keleher.com/images/test-run.png" medium="image" />
    </item>
    <item>
      <title>XKCD&#39;s &#34;Is It Worth the Time?&#34; Considered Harmful</title>
      <link>https://will-keleher.com/posts/its-not-worth-the-time-yet/</link>
      <guid>https://will-keleher.com/posts/its-not-worth-the-time-yet/</guid>
      <pubDate>Fri, 13 Dec 2024 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Automating things, even when it doesn't save time, is how you learn the skills to automate the things that will.]]></description>
    </item>
    <item>
      <title>Python patterns I learned during last year&#39;s Advent of Code</title>
      <link>https://will-keleher.com/posts/small-python-things-i-learned-during-advent-of-code/</link>
      <guid>https://will-keleher.com/posts/small-python-things-i-learned-during-advent-of-code/</guid>
      <pubDate>Wed, 13 Nov 2024 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Python is a great fit for Advent of Code style problems. Here are a few patterns I picked up that I'm going to try and use again this year.]]></description>
          <media:content url="https://will-keleher.com/posts/small-python-things-i-learned-during-advent-of-code/preview.png" medium="image" />
    </item>
    <item>
      <title>Indexes are sorted arrays (sort of)</title>
      <link>https://will-keleher.com/posts/indexes_are_like_sorted_arrays/</link>
      <guid>https://will-keleher.com/posts/indexes_are_like_sorted_arrays/</guid>
      <pubDate>Mon, 14 Aug 2023 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Thinking of B-trees and B+-trees as sorted arrays can help you reason about indexes and performance.]]></description>
          <media:content url="https://will-keleher.com/posts/indexes_are_like_sorted_arrays/preview.png" medium="image" />
    </item>
    <item>
      <title>JSDoc comments can make fixtures easier to work with</title>
      <link>https://will-keleher.com/posts/jsdoc-comments-on-fixtures/</link>
      <guid>https://will-keleher.com/posts/jsdoc-comments-on-fixtures/</guid>
      <pubDate>Sun, 23 Jul 2023 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[By auto-generating JSDoc comments on a fixture IDs file, we were able to make our fixture code simpler to work with.]]></description>
          <media:content url="https://will-keleher.com/images/fixtureId.png" medium="image" />
    </item>
    <item>
      <title>So, what can you do with a process ID?</title>
      <link>https://will-keleher.com/posts/what-can-you-do-with-a-pid/</link>
      <guid>https://will-keleher.com/posts/what-can-you-do-with-a-pid/</guid>
      <pubDate>Sat, 10 Dec 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[If you have a process ID, you can look at what files/ports a process has open, see details about how the process was started, trace it to see what work it's doing, or wait for it to complete its work. Process IDs are pretty cool!]]></description>
          <media:content url="https://will-keleher.com/posts/what-can-you-do-with-a-pid/preview.png" medium="image" />
    </item>
    <item>
      <title>Why does `zip(*[iter(s)]*n)` chunk s into n chunks in Python?</title>
      <link>https://will-keleher.com/posts/chunking-in-python/</link>
      <guid>https://will-keleher.com/posts/chunking-in-python/</guid>
      <pubDate>Sat, 10 Dec 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Understanding why `zip(*[iter(s)]*n)` chunks an input `s` into `n` chunks is a good excuse to explore iterators, iterable unpacking, list multiplication, and the zip function.]]></description>
          <media:content url="https://will-keleher.com/posts/chunking-in-python/preview.png" medium="image" />
    </item>
    <item>
      <title>Culling Containers with a Leaky Bucket</title>
      <link>https://will-keleher.com/posts/cullingcontainerswithaleakybucket/</link>
      <guid>https://will-keleher.com/posts/cullingcontainerswithaleakybucket/</guid>
      <pubDate>Mon, 24 Oct 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Containers serving production traffic can sometimes get into bad states that they can't recover from. Automatically shutting down these problem containers can make production systems more resilient until you're able to debug and fix whatever the root cause is.]]></description>
          <media:content url="https://will-keleher.com/posts/cullingcontainerswithaleakybucket/preview.png" medium="image" />
    </item>
    <item>
      <title>Setting up Image Previews using Puppeteer, Make, and CSS transforms</title>
      <link>https://will-keleher.com/posts/setting-up-image-previews/</link>
      <guid>https://will-keleher.com/posts/setting-up-image-previews/</guid>
      <pubDate>Thu, 20 Oct 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[How I set up image previews for some posts on this site using automated screenshots.]]></description>
          <media:content url="https://will-keleher.com/posts/setting-up-image-previews/preview.png" medium="image" />
    </item>
    <item>
      <title>Writing FizzBuzz in MySQL 5.7 for no good reason</title>
      <link>https://will-keleher.com/posts/fizzbuzz-in-mysql-5.7/</link>
      <guid>https://will-keleher.com/posts/fizzbuzz-in-mysql-5.7/</guid>
      <pubDate>Thu, 07 Jul 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[MySQL 5.7 makes getting a list of numbers pretty tricky, so solutions to FizzBuzz are a fun chance to explore MySQL techniques like session variables, stored routines, and cross-joined views.]]></description>
          <media:content url="https://will-keleher.com/posts/fizzbuzz-in-mysql-5.7/preview.png" medium="image" />
    </item>
    <item>
      <title>Using NodeJS&#39;s AsyncLocalStorage to Instrument a Webserver</title>
      <link>https://will-keleher.com/posts/asynclocalstorage_in_detail/</link>
      <guid>https://will-keleher.com/posts/asynclocalstorage_in_detail/</guid>
      <pubDate>Mon, 30 May 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[How to start an async storage context early in your middleware stack and set up counters to track down problem routes.]]></description>
          <media:content url="https://will-keleher.com/posts/asynclocalstorage_in_detail/preview.png" medium="image" />
    </item>
    <item>
      <title>Large Analytics SQL Queries are a Code Smell</title>
      <link>https://will-keleher.com/posts/large-sql-queries-are-bad/</link>
      <guid>https://will-keleher.com/posts/large-sql-queries-are-bad/</guid>
      <pubDate>Wed, 11 May 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Large analytics SQL queries can be unmaintainable and hard to debug. Writing large SQL queries is hard and slow! You can use temporary tables and views to break down those queries into smaller pieces that are easier to work with.]]></description>
          <media:content url="https://will-keleher.com/posts/large-sql-queries-are-bad/preview.png" medium="image" />
    </item>
    <item>
      <title>Shell Patterns for Easy Automated Code Migrations</title>
      <link>https://will-keleher.com/posts/tricks-for-automated-code-migrations/</link>
      <guid>https://will-keleher.com/posts/tricks-for-automated-code-migrations/</guid>
      <pubDate>Wed, 11 May 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Being comfortable using shell tools to do large code migrations is a superpower. Here are the patterns and techniques I find myself using often.]]></description>
          <media:content url="https://will-keleher.com/posts/tricks-for-automated-code-migrations/preview.png" medium="image" />
    </item>
    <item>
      <title>Red and Blue Function Mistakes in JavaScript</title>
      <link>https://will-keleher.com/posts/red-blue-function-mistakes-in-js/</link>
      <guid>https://will-keleher.com/posts/red-blue-function-mistakes-in-js/</guid>
      <pubDate>Fri, 25 Mar 2022 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Use of async functions in JS leads to consistent mistakes; these are the ones I see most often.]]></description>
          <media:content url="https://will-keleher.com/posts/red-blue-function-mistakes-in-js/preview.png" medium="image" />
    </item>
    <item>
      <title>Slack is the Worst Info-Radiator</title>
      <link>https://will-keleher.com/posts/slack_is_the_worst_info_radiator/</link>
      <guid>https://will-keleher.com/posts/slack_is_the_worst_info_radiator/</guid>
      <pubDate>Mon, 06 Dec 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[When we went remote, we needed to replace the in-office info-radiators that displayed info about the health of our system. Alert slack channels are often too noisy to be useful and don't display the current state of the world well.]]></description>
          <media:content url="https://will-keleher.com/images/info-radiator/small-all-good.png" medium="image" />
    </item>
    <item>
      <title>Bash Patterns I Use Weekly</title>
      <link>https://will-keleher.com/posts/4-useful-bash-patterns/</link>
      <guid>https://will-keleher.com/posts/4-useful-bash-patterns/</guid>
      <pubDate>Mon, 22 Nov 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[4 bash tricks I find myself using often that I wish I'd discovered sooner.]]></description>
          <media:content url="https://will-keleher.com/posts/4-useful-bash-patterns/preview.png" medium="image" />
    </item>
    <item>
      <title>Canary Containers at ClassDojo in Too Much Detail</title>
      <link>https://will-keleher.com/posts/canary-containers-at-classdojo-in-too-much-detail/</link>
      <guid>https://will-keleher.com/posts/canary-containers-at-classdojo-in-too-much-detail/</guid>
      <pubDate>Tue, 02 Nov 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[ClassDojo sends real traffic to canary containers to validate new builds and uses that as part of a system that safely deploys new code multiple times a day.]]></description>
    </item>
    <item>
      <title>MongoDB Performance is Disk-graceful</title>
      <link>https://will-keleher.com/posts/mongo_performance_is_disk-graceful/</link>
      <guid>https://will-keleher.com/posts/mongo_performance_is_disk-graceful/</guid>
      <pubDate>Fri, 22 Oct 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[MongoDB databases often require lots of disk I/O because documents aren't stored in a clustered index and because writing snapshots can saturate disk I/O.]]></description>
    </item>
    <item>
      <title>Node&#39;s `AsyncLocalStorage` Makes the Commons Legible</title>
      <link>https://will-keleher.com/posts/asynclocalstorage_makes_the_commons_legible/</link>
      <guid>https://will-keleher.com/posts/asynclocalstorage_makes_the_commons_legible/</guid>
      <pubDate>Wed, 18 Aug 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Node's AsyncLocalStorage can dramatically increase monolith legibility and improve performance.]]></description>
    </item>
    <item>
      <title>The 3 things I didn&#39;t understand about TypeScript</title>
      <link>https://will-keleher.com/posts/3-typescript-misunderstandings/</link>
      <guid>https://will-keleher.com/posts/3-typescript-misunderstandings/</guid>
      <pubDate>Tue, 10 Aug 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[understanding type inference, type narrowing, and structural typing is crucial to writing good TypeScript code.]]></description>
          <media:content url="https://will-keleher.com/posts/3-typescript-misunderstandings/preview.png" medium="image" />
    </item>
    <item>
      <title>HyperLogLog-orrhea: how do HyperLogsLogs work?</title>
      <link>https://will-keleher.com/posts/hyperloglog-orrhea/</link>
      <guid>https://will-keleher.com/posts/hyperloglog-orrhea/</guid>
      <pubDate>Wed, 14 Jul 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[HyperLogLogs leverage the power of hashing strings into random numbers to create remarkably accurate cardinality estimates.]]></description>
          <media:content url="https://will-keleher.com/posts/hyperloglog-orrhea/preview.png" medium="image" />
    </item>
    <item>
      <title>ERROR, WARN, and INFO aren&#39;t actionable logging levels</title>
      <link>https://will-keleher.com/posts/your_logging_taxonomy_should_be_actionable/</link>
      <guid>https://will-keleher.com/posts/your_logging_taxonomy_should_be_actionable/</guid>
      <pubDate>Tue, 13 Jul 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Logs should be actionable and the default categories of FATAL, ERROR, WARN, INFO, and DEBUG aren't precise enough.]]></description>
    </item>
    <item>
      <title>Graceful server shutdowns behind HAProxy</title>
      <link>https://will-keleher.com/posts/graceful_web-server_shutdowns_behind_haproxy/</link>
      <guid>https://will-keleher.com/posts/graceful_web-server_shutdowns_behind_haproxy/</guid>
      <pubDate>Mon, 12 Jul 2021 00:00:00 &#43;0000</pubDate>
      <description><![CDATA[Graceful shutdowns behind a load balancer are hard to do right, but they enable solid auto-scaling and safe frequent deploys.]]></description>
          <media:content url="https://will-keleher.com/posts/graceful_web-server_shutdowns_behind_haproxy/preview.png" medium="image" />
    </item>
  </channel>
</rss>
