<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>LunarOps</title>
    <link>/</link>
    <description>Recent content on LunarOps</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 05 Jul 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Grid Frequency Regulation: The Control Loop That Never Sleeps</title>
      <link>/posts/grid-frequency-regulation/</link>
      <pubDate>Sun, 05 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grid-frequency-regulation/</guid>
      <description>&lt;p&gt;The alternating current in your wall reverses direction sixty times a second in North America, fifty in most of the rest of the world, and the precision with which it holds that rhythm is one of the most consequential control problems on the planet. Frequency is not a cosmetic property of the grid; it is the grid&amp;rsquo;s only real-time, continent-wide measurement of whether generation exactly equals demand. There is no reservoir of electricity buffering supply against load — the energy is generated and consumed in the same instant, always — so the moment consumption exceeds production, the deficit is paid out of the kinetic energy of thousands of spinning generator rotors, they slow down, and the frequency falls. When production exceeds consumption, the rotors speed up and frequency rises. The number is a shared, broadcast, tamper-proof signal of the supply-demand balance, observed simultaneously by every machine on the interconnection at the speed of light, with no message bus and no polling. Keeping it pinned near 60 Hz is a layered feedback-control system that operates from milliseconds to hours, and when any layer loses the race, the lights go out for millions of people.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Catalytic Converter Works: Chemistry at 800 Degrees</title>
      <link>/posts/how-a-catalytic-converter-works/</link>
      <pubDate>Sun, 05 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-catalytic-converter-works/</guid>
      <description>&lt;p&gt;A gasoline engine is a chemically dirty device. Even a well-tuned one leaves behind a stream of carbon monoxide from incomplete combustion, unburned hydrocarbons from fuel that never fully reacted, and oxides of nitrogen forged by the sheer heat of the burn tearing apart the nitrogen and oxygen that make up most of the air it breathes. These three pollutants are the reason cities used to choke on smog, and eliminating them is not one problem but two contradictory ones. Carbon monoxide and hydrocarbons are &lt;em&gt;under-oxidized&lt;/em&gt;: they need more oxygen to finish burning into carbon dioxide and water. Nitrogen oxides are &lt;em&gt;over-oxidized&lt;/em&gt;: they need oxygen stripped away to fall back into harmless nitrogen and oxygen gas. Asking a single device to simultaneously add oxygen to one set of molecules and remove it from another, in the same white-hot gas stream, sounds like a violation of common sense. The three-way catalytic converter does exactly that, in a ceramic brick the size of a loaf of bread, and it does it well enough to strip more than 95 percent of all three pollutants out of the exhaust — as long as the engine feeds it a mixture held to a tolerance of better than one percent. This is the story of how that brick performs its contradiction, and of the surprisingly fragile chemistry that keeps it alive.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Differential Works: The Gearbox That Lets Wheels Disagree</title>
      <link>/posts/how-a-differential-works/</link>
      <pubDate>Sun, 05 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-differential-works/</guid>
      <description>&lt;p&gt;Drive a car around a corner and the outside wheels travel farther than the inside wheels. This is not a subtle effect. On a tight turn the outer front tire can trace a path several feet longer than the inner one over the same few seconds, which means it must physically rotate faster. If both driven wheels were bolted to a single solid shaft, one of them would have to slip, scrubbing rubber across the pavement and fighting the other wheel through the whole turn. The differential exists to resolve exactly this conflict: it takes one input torque from the engine and splits it to two wheels while letting each wheel choose its own speed. It is one of the oldest pieces of automotive engineering still in daily use, its core gear train essentially unchanged since the 1820s, and it is the reason your car can turn a corner without hopping, screeching, or destroying its tires. It is also the source of one of driving&amp;rsquo;s most counterintuitive failures — the reason a car with one wheel on ice can sit there spinning that wheel uselessly while the other, sitting on dry pavement, does nothing at all.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RFID and NFC: How Powerless Tags Talk Back</title>
      <link>/posts/rfid-and-nfc/</link>
      <pubDate>Sun, 05 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rfid-and-nfc/</guid>
      <description>&lt;p&gt;Hold a plastic card near a reader and it answers, instantly, with no battery inside it. That is a genuinely strange thing when you stop to think about it. A transit card frozen in a drawer for two years works the moment it enters a turnstile&amp;rsquo;s field; a passport chip, a warehouse pallet tag, a rice-grain implant under a dog&amp;rsquo;s skin, a credit card tapped at a terminal — none of them stores power, yet all of them compute a response and transmit it back on demand. The trick that makes this possible is not miniaturized batteries or clever sleep modes. It is that the tag never had power of its own to begin with. It harvests energy from the reader&amp;rsquo;s electromagnetic field, uses that borrowed energy to wake a tiny chip, and then replies not by generating its own radio signal but by &lt;em&gt;changing how much of the reader&amp;rsquo;s field it absorbs&lt;/em&gt; — a whisper made by modulating a load rather than shouting into an antenna. Understanding that one inversion, that the tag talks by listening louder and softer, unlocks the whole family of technologies from 125 kHz animal chips to the 13.56 MHz NFC in your phone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Backpropagation: How Neural Networks Actually Learn</title>
      <link>/posts/backpropagation-how-networks-learn/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/backpropagation-how-networks-learn/</guid>
      <description>&lt;p&gt;Backpropagation gets described as the thing that makes deep learning possible, which is true, and as something mysterious, which is not. Strip away the branding and it is the chain rule from first-year calculus, applied mechanically and in a specific order to a graph of arithmetic operations. A neural network is a big composite function. Training it means nudging millions of internal numbers so the function&amp;rsquo;s output gets closer to what you wanted. To nudge a number sensibly you need to know which direction moves the error down and by how much — the derivative of the loss with respect to that number. Backpropagation is the bookkeeping trick that computes every one of those millions of derivatives in a single sweep, at roughly the same cost as evaluating the network once.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Epithalon and the Khavinson Bioregulators</title>
      <link>/posts/epithalon-and-the-khavinson-bioregulators/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/epithalon-and-the-khavinson-bioregulators/</guid>
      <description>&lt;p&gt;Epithalon is the most famous product of a research program that, on paper, should be one of the more significant achievements in twentieth-century gerontology: a Soviet and then Russian scientist spending four decades and over 700 published papers building an entire class of short, tissue-specific peptides claimed to regulate gene expression and slow aging, backed by a mouse lifespan study, in vitro telomerase activation data, and a 266-patient human cohort reporting mortality reductions of up to four-fold. If even a fraction of that held up to the standard the rest of pharmacology is judged by, it would be genuinely major news. It hasn&amp;rsquo;t been independently replicated outside the lab that produced it in over twenty years, and that single fact is the load-bearing detail this entire compound class rests on.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Follistatin, ACE-031, and the Myostatin Inhibitor Gene-Doping Frontier</title>
      <link>/posts/follistatin-and-myostatin-inhibitors-gene-doping-frontier/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/follistatin-and-myostatin-inhibitors-gene-doping-frontier/</guid>
      <description>&lt;p&gt;Myostatin inhibition is the rare grey-market mechanism where the animal evidence is not exaggerated. Knockout mice grow muscles twice normal size. Belgian Blue and Piedmontese cattle carry natural loss-of-function mutations in the same gene and are visibly, dramatically &amp;ldquo;double-muscled&amp;rdquo; — a phenotype cattle breeders selected for without knowing why for over a century before the molecular cause was found. Whippets with a comparable mutation earn the nickname &amp;ldquo;bully whippets.&amp;rdquo; A human infant with a homozygous splice-site mutation in the same gene was documented in 2004, unusually muscular from birth and still visibly hypertrophied at four and a half years old. This is about as close to a slam-dunk mammalian result as biology offers, which is exactly why &amp;ldquo;follistatin&amp;rdquo; and &amp;ldquo;ACE-031&amp;rdquo; became grey-market peptide-vendor staples. The problem isn&amp;rsquo;t that the underlying biology is fake. It&amp;rsquo;s that the one clinical trial that got close to reproducing the animal effect in a targeted human population was halted by a specific, mechanistically explainable safety signal — and the vials sold online today aren&amp;rsquo;t the intervention that trial actually tested.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GHK-Cu: The Copper Peptide and the Injectable Leap</title>
      <link>/posts/ghk-cu-the-copper-peptide-and-the-injectable-leap/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ghk-cu-the-copper-peptide-and-the-injectable-leap/</guid>
      <description>&lt;p&gt;GHK-Cu occupies an unusual position among grey-market peptides: it is, by a wide margin, the best-documented compound in its category, with over fifty years of published research and real, positive randomized controlled trials behind its topical use. That&amp;rsquo;s precisely what makes its current second life — as an injectable, systemic &amp;ldquo;anti-aging&amp;rdquo; and &amp;ldquo;gene-resetting&amp;rdquo; product sold through the same unregulated channels as far shakier peptides — worth examining closely. The topical evidence is genuinely good. The injectable claims built on top of it are a different, much less supported story, and conflating the two is the central marketing move keeping this compound&amp;rsquo;s grey-market business alive.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IGF-1 LR3 and PEG-MGF: The Untested Growth Factors</title>
      <link>/posts/igf-1-lr3-and-peg-mgf-the-untested-growth-factors/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/igf-1-lr3-and-peg-mgf-the-untested-growth-factors/</guid>
      <description>&lt;p&gt;IGF-1 LR3 and PEG-MGF are sold as two different products but they&amp;rsquo;re really the same story told twice: take a growth-factor pathway with a well-documented, dose-dependent anabolic effect, engineer a version with higher potency or longer half-life than the body would ever produce naturally, and skip the part where that engineered version gets tested in a controlled human trial before it reaches a vial. The molecular biology behind both compounds is legitimate and extensively published — this isn&amp;rsquo;t a case of invented mechanism. It&amp;rsquo;s a case where the marketing quietly substitutes &amp;ldquo;we understand how this pathway works&amp;rdquo; for &amp;ldquo;we know what happens when you inject an unregulated, non-physiological dose of it into a healthy adult,&amp;rdquo; and the one drug in this family that actually went through FDA approval carries a warning label serious enough to require routine blood glucose monitoring.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MOTS-c and the Mitochondrial-Derived Peptide Frontier</title>
      <link>/posts/mots-c-and-the-mitochondrial-derived-peptide-frontier/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mots-c-and-the-mitochondrial-derived-peptide-frontier/</guid>
      <description>&lt;p&gt;Mitochondria have a second job nobody planned for them. For decades the 16,569 base pairs of human mitochondrial DNA were treated as a maintenance manual: thirteen genes for oxidative-phosphorylation proteins, twenty-two tRNAs, two rRNAs, all of it dedicated to keeping the organelle&amp;rsquo;s own machinery running. MOTS-c broke that model. It is a 16-amino-acid peptide translated from an alternative open reading frame sitting inside the mitochondrial 12S rRNA gene — a region that was never supposed to code for anything exported outside the organelle — and it turns out to circulate in blood, respond to exercise, and activate one of the cell&amp;rsquo;s master metabolic switches from a distance. That discovery reframed the mitochondrion as an endocrine organ. It also handed the grey-market peptide trade a genuinely novel biological story to sell, and the marketing has now outrun the single human trial that ever tested a version of this molecule in people.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Semax and Selank: The Russian Neuropeptide School</title>
      <link>/posts/semax-and-selank-the-russian-neuropeptide-school/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/semax-and-selank-the-russian-neuropeptide-school/</guid>
      <description>&lt;p&gt;Semax and Selank occupy a strange middle ground that most grey-market peptides never reach: they are real, approved, prescribed drugs — just not here. Both sit on the Russian Federation&amp;rsquo;s List of Vital and Essential Drugs, both have been in clinical use in Russia for cognitive and anxiety disorders for over two decades, and both rest on a mechanistic story — BDNF upregulation, melanocortin and GABAergic signaling — that is genuinely more developed than almost any over-the-counter nootropic sold in the West. That&amp;rsquo;s exactly what makes them tricky. The Western nootropics grey market imports the &amp;ldquo;clinically approved in Russia&amp;rdquo; credential as if it were equivalent to an FDA approval, while quietly leaving behind the context that makes Russian approval a much weaker evidentiary signal than the phrase implies. The honest question isn&amp;rsquo;t whether these peptides do anything — the mechanistic and small-trial evidence says they probably do something — but whether &amp;ldquo;something, demonstrated mostly in small unblinded Russian trials that nobody outside Russia has reproduced&amp;rdquo; is the same thing the marketing is selling.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TB-500 and the Thymosin Beta-4 Evidence Gap</title>
      <link>/posts/tb-500-and-the-thymosin-beta-4-evidence-gap/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tb-500-and-the-thymosin-beta-4-evidence-gap/</guid>
      <description>&lt;p&gt;TB-500 has one of the stranger origin stories in the grey-market peptide world: it didn&amp;rsquo;t arrive in human wellness circles through a failed clinical trial, like most of the compounds in this category, but through a horse-racing doping scandal. The molecule it&amp;rsquo;s derived from, thymosin beta-4, is a real and mechanistically well-characterized cytoskeletal-regulatory protein with a genuine pharmaceutical development history behind a related but distinct formulation. TB-500 the synthetic fragment, however — the version actually sold in injectable vials to athletes and recreational users — has, as of 2026, never completed a single published human clinical trial for any tissue-repair indication. That&amp;rsquo;s not a subtle caveat buried in fine print; it&amp;rsquo;s the central fact of the compound&amp;rsquo;s regulatory and evidentiary status, and it&amp;rsquo;s almost entirely absent from the marketing built around it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of BSD: The Unix That Lost the War and Won the World</title>
      <link>/posts/the-story-of-bsd/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-bsd/</guid>
      <description>&lt;p&gt;There is a strong case that BSD is the most influential operating system almost nobody thinks they use. The networking code that carried the early internet was BSD&amp;rsquo;s. The &lt;code&gt;vi&lt;/code&gt; editor, the C shell, and the sockets API that every network program on earth still calls were born at Berkeley. The Mac on your desk runs a kernel wrapped in BSD userland; every PlayStation from the PS3 onward boots a FreeBSD derivative; Netflix streams a large fraction of the internet&amp;rsquo;s video off FreeBSD servers pushing 400 gigabits per second. And yet BSD &amp;ldquo;lost.&amp;rdquo; In the one moment it could have owned the personal-computer era — the early 1990s, when a free, mature, battle-tested Unix could have captured the exploding market of cheap Intel machines — it was frozen by a lawsuit, and a technically unremarkable student kernel called Linux walked straight into the gap. The story of BSD is the story of how the better-engineered system lost the war for mindshare and won almost everything else by disappearing into the infrastructure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Ethernet: How a Shared Wire Won the Network</title>
      <link>/posts/the-story-of-ethernet/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-ethernet/</guid>
      <description>&lt;p&gt;Ethernet is the most successful networking technology in history, and by the tidy logic of engineering it should never have won. Its founding idea was to let every machine on a shared wire transmit whenever it felt like it, detect the inevitable collisions after the fact, and recover by waiting a random interval before trying again. This is not a design; it is organized chaos. Its competitors — Token Ring from IBM, Token Bus from the factory-automation world — were deterministic, fair, and backed by the largest computer company on earth. They guaranteed that no packet would ever collide and that every station would get a predictable turn. Ethernet guaranteed nothing except that, on average, it would sort itself out. It is now in every wall jack, every data center, every laptop dongle, running at a hundred gigabits, while Token Ring is a museum piece. The story of how the messy design beat the elegant ones is a story about standards politics, cheap hardware, and a bet that the network&amp;rsquo;s own randomness could be tamed by a clever backoff algorithm.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of SSH: How a Stolen Password Became the Internet&#39;s Front Door</title>
      <link>/posts/the-story-of-ssh/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-ssh/</guid>
      <description>&lt;p&gt;Every time an administrator opens a terminal to a server, a deploy pipeline pushes code, a backup script copies files between machines, or a developer runs &lt;code&gt;git push&lt;/code&gt;, the traffic almost certainly rides inside SSH. It is the single most universal piece of security infrastructure on the internet, so ubiquitous that it has become invisible — a utility as taken-for-granted as the electrical outlet. And like a lot of foundational infrastructure, it exists because of a specific, avoidable disaster. In 1995 the network at Helsinki University of Technology was compromised by a password sniffer, a program silently reading login credentials as they crossed the wire in plain text, because that is how remote access worked at the time: &lt;code&gt;telnet&lt;/code&gt;, &lt;code&gt;rlogin&lt;/code&gt;, &lt;code&gt;rsh&lt;/code&gt;, and &lt;code&gt;ftp&lt;/code&gt; all sent your password unencrypted for anyone on the path to read. A researcher named Tatu Ylönen wrote a replacement over a few weeks. He gave it away. Within months tens of thousands of people were using it, and within a few years a fork of his work maintained by a group of security-obsessed operating-system developers had become the default on nearly every computer that matters.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of the GNU Project: The Operating System That Refused to Be Owned</title>
      <link>/posts/the-story-of-the-gnu-project/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-the-gnu-project/</guid>
      <description>&lt;p&gt;Almost every general-purpose computer on earth runs software from a project that set out, four decades ago, to make a specific kind of ownership impossible. When you type &lt;code&gt;bash&lt;/code&gt;, compile with &lt;code&gt;gcc&lt;/code&gt;, edit in &lt;code&gt;emacs&lt;/code&gt;, run &lt;code&gt;tar&lt;/code&gt; or &lt;code&gt;grep&lt;/code&gt; or &lt;code&gt;sed&lt;/code&gt;, or boot a machine through &lt;code&gt;grub&lt;/code&gt;, you are using GNU — the operating system Richard Stallman announced in 1983 with the flat declaration that he was going to write a complete Unix-compatible system and give it away, because the alternative was participating in something he considered wrong. GNU is not merely old software that survived. It is the load-bearing userland of the Linux world, the reason the license under which most of the world&amp;rsquo;s infrastructure is distributed exists at all, and the origin of an idea — copyleft — that turned a copyright statute meant to restrict copying into a legal machine that forces sharing. The technology matters, but the story is really about a lawyer&amp;rsquo;s trick wrapped around a moral argument, and about what happens when the one piece you cannot finish is the one piece someone else finishes for you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tokenization and Byte-Pair Encoding: How Text Becomes Numbers</title>
      <link>/posts/tokenization-and-byte-pair-encoding/</link>
      <pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tokenization-and-byte-pair-encoding/</guid>
      <description>&lt;p&gt;A large language model has never read a word in its life. Before a single matrix multiply happens, the string you typed is chopped into pieces, and each piece is looked up in a table and replaced by an integer. The model sees only those integers — a sequence of token IDs — and everything it &amp;ldquo;knows&amp;rdquo; about language is really a statistical relationship between numbers in that vocabulary. The layer that does the chopping is the tokenizer, and for almost every model you have heard of, the algorithm inside it is byte-pair encoding. It is the least glamorous part of the stack and one of the most consequential. Tokenization decides how long your prompt is, how much you pay, how well the model handles Arabic or Python or a phone number, and why a system that can write a sonnet cannot reliably count the letters in &amp;ldquo;strawberry.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Antimicrobial Peptides: The Innate Immune System&#39;s Own Antibiotics</title>
      <link>/posts/antimicrobial-peptides/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/antimicrobial-peptides/</guid>
      <description>&lt;p&gt;Every multicellular organism that has ever been studied for it — plants, insects, amphibians, humans — makes its own antibiotics, and it made them hundreds of millions of years before a mold spore contaminated Alexander Fleming&amp;rsquo;s petri dish in 1928. These molecules are antimicrobial peptides (AMPs): short chains of amino acids, usually under 50 residues, that kill bacteria, fungi, and some enveloped viruses not by jamming a single metabolic enzyme the way most prescription antibiotics do, but by physically tearing open the microbial cell membrane. That mechanism is old, it&amp;rsquo;s broad-spectrum, and it&amp;rsquo;s remarkably hard for a microbe to evolve resistance against by mutating one gene — which is exactly why, as conventional antibiotic resistance climbs, the pharmaceutical industry keeps circling back to a molecule class the human innate immune system has been quietly relying on since before the immune system had T cells.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AOD-9604 and the GH Fragment Marketing Gap</title>
      <link>/posts/aod-9604-and-the-gh-fragment-marketing-gap/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aod-9604-and-the-gh-fragment-marketing-gap/</guid>
      <description>&lt;p&gt;AOD-9604 is what happens when a real, well-reasoned drug-development idea fails its pivotal trial and then gets a second life anyway, sold on the strength of the idea rather than the data that idea eventually produced. The underlying science — that growth hormone&amp;rsquo;s fat-burning activity can be isolated from its growth-promoting activity in a small fragment of the molecule — is legitimate 1990s endocrinology from a real academic lab. The clinical outcome, a Phase 2b trial that enrolled over 500 obese subjects and found no statistically significant weight-loss benefit over placebo, is just as real, and it&amp;rsquo;s the part that grey-market listings for &amp;ldquo;AOD-9604 research peptide&amp;rdquo; almost never mention.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bayes&#39; Theorem for Engineers: The Base-Rate Trap That Fools Doctors, Juries, and Alert Dashboards</title>
      <link>/posts/bayes-theorem-for-engineers/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bayes-theorem-for-engineers/</guid>
      <description>&lt;p&gt;A test that is 99% accurate for a condition that only 1 in 10,000 people have will, on a positive result, still be wrong far more often than it&amp;rsquo;s right — and the reason has nothing to do with the test being bad. It has to do with a fact almost everyone&amp;rsquo;s intuition skips over: how rare the thing you&amp;rsquo;re testing for was &lt;em&gt;before&lt;/em&gt; the test ever ran. That prior rarity is not a footnote to the calculation, it&amp;rsquo;s usually the dominant term in it, and ignoring it is called the base-rate fallacy — a reasoning error so consistent that it fools trained physicians interpreting their own field&amp;rsquo;s tests, juries weighing DNA evidence, and engineers staring at an alert dashboard convinced a rare failure mode just fired. Bayes&amp;rsquo; theorem is the formal fix. It isn&amp;rsquo;t exotic machinery reserved for statisticians; it&amp;rsquo;s arithmetic anyone can do with a pencil, and once the natural-frequency version of it clicks, the base-rate trap stops being able to fool you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BPC-157 and the Research-Peptide Gray Market</title>
      <link>/posts/bpc-157-research-peptide-gray-market/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bpc-157-research-peptide-gray-market/</guid>
      <description>&lt;p&gt;BPC-157 occupies a strange position in the peptide world: it has a legitimate discovery history, a genuinely unusual and well-characterized structure, and one of the more consistent animal-study track records of any research peptide — and it is also the peptide most commonly self-injected by people who found it through a forum thread or a fitness-influencer post, sourced from vendors who label it &amp;ldquo;not for human use&amp;rdquo; while marketing it directly to humans. Those two facts are not in tension so much as they&amp;rsquo;re two separate stories that get conflated constantly: the science is real but incomplete, and the supply chain that most users actually rely on has almost nothing to do with the science at all. Separating those threads is the point of this post.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CagriSema and the Amylin Comeback</title>
      <link>/posts/cagrisema-and-the-amylin-comeback/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cagrisema-and-the-amylin-comeback/</guid>
      <description>&lt;p&gt;CagriSema is a bet that the GLP-1 story was missing a second hormone. Cagrilintide, a long-acting amylin analog, and semaglutide, the GLP-1 agonist already sold as Wegovy and Ozempic, are combined in one weekly injection on the theory that amylin and GLP-1 suppress appetite through genuinely separate brain circuits, and that stacking them should beat either one alone by more than simple addition would predict. The Phase 3 REDEFINE program mostly backed that theory up: 22.7% average weight loss at 68 weeks in the lead obesity trial, the largest number Novo Nordisk has published for any of its combinations. Then a head-to-head trial against Eli Lilly&amp;rsquo;s tirzepatide reported out, and CagriSema came in second — 23.0% versus 25.5% — missing its own pre-specified non-inferiority bar. That result doesn&amp;rsquo;t erase what amylin brings to the table; it just means the third major receptor mechanism to enter this race turned out to be a strong contender rather than a category-ending one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Collagen Peptides: What the Evidence Actually Says</title>
      <link>/posts/collagen-peptides-what-the-evidence-says/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/collagen-peptides-what-the-evidence-says/</guid>
      <description>&lt;p&gt;The standard skeptical dismissal of collagen supplements goes like this: collagen is a protein, digestion breaks proteins down into amino acids, and your gut has no way of knowing whether a given amino acid came from a $60 collagen powder or a chicken breast, so a swallowed collagen peptide can&amp;rsquo;t possibly reach your skin or joints intact to do anything special. That argument is intuitive, widely repeated, and incomplete — it correctly describes what happens to most of a collagen protein and misses what happens to a specific fragment of it. A dipeptide called prolyl-hydroxyproline (Pro-Hyp) survives digestion largely intact, crosses into the bloodstream at measurable concentrations, and has documented biological activity on the cells that make collagen. That&amp;rsquo;s a real mechanism, published in peer-reviewed pharmacokinetic studies, not a marketing claim. The harder, more interesting question — and the one worth spending an entire post on — is whether that real mechanism translates into a clinical benefit large enough to justify the supplement industry built on top of it, and here the evidence gets genuinely contested rather than simply positive.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GHRH and GHRP Secretagogues: Asking the Pituitary Instead of Replacing It</title>
      <link>/posts/ghrh-ghrp-secretagogues/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ghrh-ghrp-secretagogues/</guid>
      <description>&lt;p&gt;The single most important fact about growth hormone secretagogues is also the one most often garbled in the marketing built around them: sermorelin, ipamorelin, CJC-1295, and their relatives do not put growth hormone into your body. They stimulate your own pituitary gland to release more of its own growth hormone, through receptors distinct from the ones synthetic HGH itself works on downstream. That&amp;rsquo;s a real mechanistic difference from injecting recombinant somatropin directly, and it has real physiological consequences — it leaves the body&amp;rsquo;s negative feedback loop intact, which injected HGH bypasses entirely. But &amp;ldquo;works through a different, more natural-sounding mechanism&amp;rdquo; and &amp;ldquo;safe, effective anti-aging treatment&amp;rdquo; are two different claims, and the peptide-secretagogue industry has spent two decades collapsing the distance between them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GLP-1 Agonists, Honestly</title>
      <link>/posts/glp-1-agonists-honestly/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/glp-1-agonists-honestly/</guid>
      <description>&lt;p&gt;A hormone your gut has been secreting after every meal for your entire life, with a native half-life measured in single-digit minutes, is now the active ingredient in some of the best-selling drugs in pharmaceutical history — not because anyone invented a new biological mechanism, but because someone figured out how to keep that hormone&amp;rsquo;s signal turned on for a full week instead of two minutes. Semaglutide (Ozempic, Wegovy) and tirzepatide (Mounjaro, Zepbound) are GLP-1 receptor agonists, and the honest version of their story is neither the miracle-cure framing nor the fad-drug dismissal — it&amp;rsquo;s a real, mechanistically well-understood intervention in the incretin system, with real effect sizes, real side effects, a real muscle-loss trade-off, and a real answer to what happens when you stop, all of which are more interesting and more useful to know than either extreme.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GLP-2 Analogs for Short Bowel</title>
      <link>/posts/glp-2-analogs-for-short-bowel/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/glp-2-analogs-for-short-bowel/</guid>
      <description>&lt;p&gt;Almost every peptide hormone covered on this site so far has been in the business of making people eat less. GLP-2 is in the opposite business: making the intestine itself grow. It&amp;rsquo;s produced from the exact same proglucagon precursor gene as GLP-1, secreted by the same intestinal L-cells, released after the same meals — and instead of suppressing appetite, it drives crypt-cell proliferation, villus growth, and blood flow expansion in the small intestine&amp;rsquo;s mucosal lining. For most people that trophic signal is a quiet, unremarkable part of normal gut maintenance. For a small population of patients who have lost most of their small intestine to surgery, disease, or injury, GLP-2 agonism is the only pharmacological lever available that can coax the remaining bowel into absorbing more of what they eat — and it is, quite literally, a lifeline away from spending the rest of their life connected to an intravenous feeding line. Teduglutide, approved in 2012, was the first drug built on that mechanism. Apraglutide and glepaglutide are the second generation, engineered specifically to fix teduglutide&amp;rsquo;s biggest practical failure: nobody wants to give themselves a daily injection for the rest of their life if a weekly one works just as well.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Peptide Drugs Are Made</title>
      <link>/posts/how-peptide-drugs-are-made/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-peptide-drugs-are-made/</guid>
      <description>&lt;p&gt;A pharmaceutical company manufacturing tirzepatide at commercial scale is, at the chemical level, doing something conceptually identical to what Bruce Merrifield did on a lab bench in 1963: attaching one amino acid to the end of a growing chain, over and over, in a specific sequence, until the target molecule is complete. The chemistry that won Merrifield the 1984 Nobel Prize in Chemistry is still the foundation of essentially every peptide drug manufactured today, and the honest story of how a peptide drug actually gets made is less about any single clever reaction and more about how a deceptively simple repeated cycle — deprotect, couple, wash, repeat — becomes a genuine manufacturing and cost engineering problem once you need kilograms of a 30-plus-residue molecule at pharmaceutical purity.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Insulin: The Original Blockbuster Peptide</title>
      <link>/posts/insulin-the-original-blockbuster-peptide/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/insulin-the-original-blockbuster-peptide/</guid>
      <description>&lt;p&gt;Every major technology that now defines the peptide and protein drug industry — purification from a natural source at industrial scale, genetic engineering in bacteria, and deliberate amino-acid substitution to tune a molecule&amp;rsquo;s pharmacokinetics — was first proven out on the same drug: insulin. It is, by a wide margin, the oldest blockbuster peptide, first isolated in 1921 from dog pancreases in a University of Toronto laboratory and still, over a century later, one of the best-selling drug classes on earth. The story of how insulin went from a crude, impure organ extract to a genetically engineered molecule redesigned at the amino-acid level for a specific absorption curve is, in miniature, the entire history of how the biopharmaceutical industry learned to manufacture peptide drugs at all.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MariTide and the Antagonist Paradox</title>
      <link>/posts/maritide-and-the-antagonist-paradox/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/maritide-and-the-antagonist-paradox/</guid>
      <description>&lt;p&gt;MariTide is the drug in the current obesity-pharmacology wave that shouldn&amp;rsquo;t work by the field&amp;rsquo;s own logic, and does anyway. Tirzepatide&amp;rsquo;s whole design premise is that activating the GIP receptor alongside the GLP-1 receptor makes GLP-1 agonism more effective — that&amp;rsquo;s the entire reason it outperforms semaglutide. MariTide, Amgen&amp;rsquo;s maridebart cafraglutide, pairs GLP-1 agonism with GIP receptor &lt;em&gt;antagonism&lt;/em&gt;, blocking the exact receptor tirzepatide spends its second binding site activating, and produces weight loss in the same range: up to 20% of body weight at 52 weeks in its Phase 2 obesity trial. Both directions work. The field does not yet have a fully unified account of why, and Amgen is now running a 72-week Phase 3 program, MARITIME, to find out whether that effect holds up at scale, whether the drug&amp;rsquo;s real tolerability problem can be engineered around, and whether monthly dosing — its other headline claim — survives contact with a wider patient population.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Melanotan and the Peptide Underground</title>
      <link>/posts/melanotan-and-the-peptide-underground/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/melanotan-and-the-peptide-underground/</guid>
      <description>&lt;p&gt;Melanotan is a rare case in the peptide underground where the gray-market compound and the FDA-approved drug trace back to the exact same research program, and diverged only because one version of the molecule was engineered for receptor selectivity and the other wasn&amp;rsquo;t. Afamelanotide (Scenesse), approved by the FDA in 2019 for a rare light-sensitivity disorder, and melanotan II, the unregulated tanning-and-libido peptide sold through gray-market vendors and self-injected by users who found it through a TikTok trend, both descend from the same 1980s University of Arizona research into melanocortin receptor biology. The difference between &amp;ldquo;legitimate, tightly regulated therapeutic&amp;rdquo; and &amp;ldquo;banned substance linked to melanoma case reports and priapism emergencies&amp;rdquo; here isn&amp;rsquo;t the underlying science — it&amp;rsquo;s selectivity, dosing control, and everything downstream of who&amp;rsquo;s allowed to administer the drug and how.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Multi-Receptor Peptide Design: One Molecule, Several Targets</title>
      <link>/posts/multi-receptor-peptide-design/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/multi-receptor-peptide-design/</guid>
      <description>&lt;p&gt;A receptor doesn&amp;rsquo;t care what you call the molecule that binds it — only what that binding does to the receptor&amp;rsquo;s shape. That distinction is the entire basis of modern peptide drug design: agonist, antagonist, and the newer, stranger category of biased agonist are not different kinds of molecules, they&amp;rsquo;re different descriptions of what happens to one receptor&amp;rsquo;s conformation and downstream signaling when something docks into it. Once you take that framing seriously, the next design move follows almost naturally — if a single peptide can be tuned to do one specific thing to one receptor, there is no fundamental reason it can&amp;rsquo;t be tuned to do specific, independently chosen things to two or three receptors at once. Tirzepatide (GLP-1 plus GIP), retatrutide (GLP-1 plus GIP plus glucagon), and MariTide (GLP-1 agonism paired with GIP &lt;em&gt;antagonism&lt;/em&gt; in the same molecule) are not incremental tweaks on semaglutide. They&amp;rsquo;re a different design philosophy, and understanding why it works requires starting with what agonism and antagonism actually mean at the molecular level.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Natriuretic Peptides as Diagnostics: How a Hormone Became a Blood Test</title>
      <link>/posts/natriuretic-peptides-as-diagnostics/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/natriuretic-peptides-as-diagnostics/</guid>
      <description>&lt;p&gt;A stretched heart muscle cell does something most cells never do: it secretes a hormone whose entire job is to tell the kidneys and blood vessels to relieve the pressure the heart is under. That hormone, B-type natriuretic peptide, and the inactive fragment produced alongside it, NT-proBNP, have become two of the most frequently ordered blood tests in cardiology and emergency medicine — not because anyone designed them as diagnostic markers, but because the same cleavage event that activates the hormone happens to dump a second, stable, easily measured molecule into the bloodstream in a fixed, predictable ratio. Understanding why the test works the way it does — and where it quietly doesn&amp;rsquo;t — starts with understanding the actual physiological system the heart is running, not just the reference range printed on a lab report.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Oral Peptide Delivery: Getting a Molecule Past the Gut Alive</title>
      <link>/posts/oral-peptide-delivery/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/oral-peptide-delivery/</guid>
      <description>&lt;p&gt;A peptide injected under the skin has a straight shot to the bloodstream. A peptide swallowed as a pill has to survive a stomach built to hydrolyze proteins, an intestine lined with enzymes whose entire job is cutting peptide bonds, a mucus layer designed to trap and clear foreign material, and an epithelial wall stitched together by junctions that block anything larger than a small sugar molecule. Oral bioavailability for an unprotected peptide typically lands somewhere between 0.1% and 2% — meaning 98 to 99.9% of the dose never makes it into circulation at all. That number is why, for most of the last century, &amp;ldquo;peptide drug&amp;rdquo; has been synonymous with &amp;ldquo;injectable drug,&amp;rdquo; and why the handful of technologies that have cracked single-digit oral bioavailability count as genuine engineering achievements rather than incremental tweaks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Peptide Hormones vs Steroid Hormones: Two Signaling Systems, Two Different Speeds</title>
      <link>/posts/peptide-hormones-vs-steroid-hormones/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/peptide-hormones-vs-steroid-hormones/</guid>
      <description>&lt;p&gt;Whether a hormone can dissolve in water decides almost everything else about how it works — its receptor location, its mechanism, its onset time, and how long its effects last. That single physical property, solubility, sorts the body&amp;rsquo;s hormones into two mechanistically distinct camps that don&amp;rsquo;t share intermediate ground: peptide hormones, built from amino acids and unable to cross a lipid membrane on their own, versus steroid hormones, built from cholesterol and able to diffuse straight through it. The peptide route stays outside the cell and triggers an amplifying relay of second messengers. The steroid route goes straight to the nucleus and edits which genes get read. Neither approach is more sophisticated than the other — they&amp;rsquo;re optimized for different jobs, on different timescales, and the mismatch between how fast each one acts is not a footnote, it&amp;rsquo;s the entire reason the body maintains both systems instead of picking one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Petrelintide and the Amylin-Only Bet</title>
      <link>/posts/petrelintide-and-the-amylin-only-bet/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/petrelintide-and-the-amylin-only-bet/</guid>
      <description>&lt;p&gt;Every amylin drug that&amp;rsquo;s reached late-stage trials so far has been a supporting act to a GLP-1 lead. Pramlintide was always an insulin adjunct. CagriSema pairs cagrilintide with semaglutide specifically because Novo Nordisk&amp;rsquo;s own data showed cagrilintide alone was the weakest of the three arms in its lead trial — 11.8% weight loss versus semaglutide&amp;rsquo;s 16.1% and the combination&amp;rsquo;s 22.7%. Petrelintide is Zealand Pharma&amp;rsquo;s bet that amylin doesn&amp;rsquo;t need the GLP-1 half of that pairing at all: a once-weekly amylin analog dosed as monotherapy, with no incretin co-administration, that produced 10.7% weight loss against 1.7% placebo in its lead Phase 2b trial — and did it with no reported vomiting and no gastrointestinal-related discontinuations at the maximally effective dose. That tolerability profile, not the weight-loss number itself, is the actual headline. It&amp;rsquo;s the first reasonably powered clinical evidence that an amylin-only mechanism can produce a clinically meaningful result while sidestepping the nausea-and-vomiting burden that defines the GLP-1 experience for a meaningful fraction of patients.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PT-141 (Bremelanotide) and the Arousal Pathway</title>
      <link>/posts/pt-141-bremelanotide-and-the-arousal-pathway/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pt-141-bremelanotide-and-the-arousal-pathway/</guid>
      <description>&lt;p&gt;Bremelanotide is unusual among grey-market peptides in that the FDA-approved version and the unregulated version are, chemically, the exact same molecule — sold under the brand name Vyleesi in a single-use autoinjector pen with a prescribing physician on one end, and sold as &amp;ldquo;PT-141&amp;rdquo; in unmarked vials and nasal sprays by peptide vendors with nobody on the other end at all. The molecule&amp;rsquo;s central mechanism — hijacking the same melanocortin signaling pathway that governs skin pigmentation to instead drive sexual arousal from inside the hypothalamus — is genuinely interesting pharmacology, not marketing spin. What it isn&amp;rsquo;t is a simple, side-effect-free arousal switch, and the gap between the FDA label&amp;rsquo;s actual data and the grey-market pitch is where this one gets worth examining closely.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Retatrutide: The Triple Agonist Pushing Past Tirzepatide</title>
      <link>/posts/retatrutide-the-triple-agonist/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/retatrutide-the-triple-agonist/</guid>
      <description>&lt;p&gt;Retatrutide&amp;rsquo;s headline numbers are hard to overstate without sounding like marketing copy, which is exactly why the trial data underneath them deserves a closer look than the press releases give it: 28.3% average body weight loss at the highest dose in its pivotal general-obesity trial, and liver fat reductions exceeding 80% in patients with elevated liver fat at baseline — both larger than any previously reported result for an injectable peptide therapeutic. Those numbers come from activating a third receptor, glucagon, on top of the GLP-1 and GIP mechanism tirzepatide already uses, and that third mechanism is not a free upgrade. It also produces a measurable, dose-dependent increase in resting heart rate that neither semaglutide nor tirzepatide carries at comparable magnitude — a real trade-off, not a footnote, and one the ongoing Phase 3 program is specifically designed to characterize before any approval decision gets made.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Signal Peptides and Protein Trafficking: The Address Label Every Secreted Protein Carries</title>
      <link>/posts/signal-peptides-and-protein-trafficking/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/signal-peptides-and-protein-trafficking/</guid>
      <description>&lt;p&gt;A cell makes thousands of different proteins in the same shared cytoplasm, and somehow every one of them ends up in the right place — secreted into the blood, embedded in the plasma membrane, folded correctly inside the endoplasmic reticulum — without a supervisor sorting them by hand. The mechanism is a short stretch of amino acids, typically the first 15 to 30 residues synthesized, that functions as an address label read by a dedicated cellular machine before the rest of the protein has even finished being built. That address label is the signal peptide, its discovery earned Günter Blobel the 1999 Nobel Prize in Physiology or Medicine, and the machinery that reads it has become, decades later, a genuine engineering lever in how biopharmaceutical companies manufacture peptide and protein drugs at scale — get the wrong signal peptide on a therapeutic protein and yield can drop by an order of magnitude for reasons that have nothing to do with the drug molecule itself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Survodutide and Mazdutide: The Glucagon Bet</title>
      <link>/posts/survodutide-and-mazdutide-the-glucagon-bet/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/survodutide-and-mazdutide-the-glucagon-bet/</guid>
      <description>&lt;p&gt;Glucagon has spent its entire pharmacological life on the wrong side of the metabolic ledger. It&amp;rsquo;s the hormone your pancreas releases when blood sugar drops too low, and its job is to raise it back up — by telling the liver to break down glycogen and manufacture new glucose. Every diabetes textbook treats it as insulin&amp;rsquo;s antagonist, the thing you inject in an emergency to reverse a hypoglycemic crash. So building an obesity drug that deliberately activates the glucagon receptor sounds, on its face, like designing a car with a mechanism for occasionally applying the brakes to make it accelerate faster. Two companies have bet real Phase 3 programs on the idea anyway: Boehringer Ingelheim&amp;rsquo;s survodutide and Innovent Biologics&amp;rsquo; mazdutide, both GLP-1/glucagon dual agonists, both now reporting weight-loss and metabolic results large enough to make the bet look reasonable — provided the GLP-1 half of the molecule keeps the glucagon half&amp;rsquo;s blood-sugar effect in check.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Peptide Half-Life Problem</title>
      <link>/posts/the-peptide-half-life-problem/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-peptide-half-life-problem/</guid>
      <description>&lt;p&gt;Native glucagon-like peptide-1 has a plasma half-life of roughly two minutes. Semaglutide, a molecule with the same sequence backbone at both ends and only a handful of chemical differences in between, has a half-life of about a week. That is a factor of roughly five thousand between the peptide your gut secretes after a meal and the peptide Novo Nordisk sells in a pen. Nothing about the receptor pharmacology explains that gap. All of it comes from a small stack of chemical tricks that keep the molecule out of the mouths of proteases and away from the drain of the kidney glomerulus. Understanding those tricks is the difference between reading peptide-drug marketing and reading a peptide-drug patent.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Turbochargers and Forced Induction: Making Power From Exhaust the Engine Was Already Throwing Away</title>
      <link>/posts/turbochargers-and-forced-induction/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/turbochargers-and-forced-induction/</guid>
      <description>&lt;p&gt;Every naturally aspirated engine throws away most of the energy in its fuel as hot, fast-moving exhaust gas — a turbocharger&amp;rsquo;s entire premise is that this waste stream, which is going to leave the tailpipe anyway, can be made to do useful work first, for a fuel-economy cost close to zero. That single idea — recovering energy the engine was already discarding, rather than spending crankshaft power to force more air in — is what separates a turbocharger from its older, mechanically simpler cousin the supercharger, and it&amp;rsquo;s why turbocharging displaced naturally aspirated and supercharged engines across nearly the entire mainstream automotive industry over the past two decades. But the free lunch has a catch: the turbine can only spin as fast as the exhaust flowing through it, which means boost doesn&amp;rsquo;t arrive instantly, and an entire subsystem of wastegates, blow-off valves, and (more recently) electric assist exists specifically to manage the mismatch between what the engine wants right now and what the exhaust stream can actually deliver.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What a Peptide Actually Is: The Chemistry Between an Amino Acid and a Protein</title>
      <link>/posts/what-a-peptide-actually-is/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/what-a-peptide-actually-is/</guid>
      <description>&lt;p&gt;A peptide is not a different kind of molecule from a protein — it&amp;rsquo;s the same kind of molecule, made by the exact same chemical reaction, just short enough that the size still matters to how the body handles it. That size boundary is not pedantry. It is the single fact that determines whether a molecule survives your stomach acid, whether it can be manufactured as a pill instead of an injection, and whether the immune system treats it as background nutrition or something worth mounting a response to. Understanding what a peptide actually is means understanding one reaction (the peptide bond), one assembly line (the ribosome), one demolition crew (proteolytic enzymes), and the specific, non-arbitrary place where &amp;ldquo;peptide&amp;rdquo; stops and &amp;ldquo;protein&amp;rdquo; begins.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Black-Scholes for Engineers: Options Pricing as a Diffusion Problem</title>
      <link>/posts/black-scholes-for-engineers/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/black-scholes-for-engineers/</guid>
      <description>&lt;p&gt;Every options trading desk quotes prices from a formula that, if you strip away the dollar signs, is identical in structure to the equation that describes heat spreading through a metal rod. That is not a metaphor — it is a literal, provable change of variables. The Black-Scholes-Merton equation is a parabolic partial differential equation, and with the right substitution it &lt;em&gt;becomes&lt;/em&gt; the one-dimensional heat equation, &lt;code&gt;∂u/∂τ = ∂²u/∂x²&lt;/code&gt;, the same equation Fourier wrote down in 1822 to describe conduction. Options pricing, at its mathematical core, is a diffusion problem: uncertainty about a future stock price spreads forward in time the same way heat spreads forward through a solid, and the option&amp;rsquo;s value today is the &amp;ldquo;temperature&amp;rdquo; you&amp;rsquo;d measure by looking backward from a known boundary condition at expiry. This post derives the equation from first principles the way an engineer would — as a hedge argument plus a stochastic calculus identity, not as a memorized formula — states the assumptions that make it solvable in closed form, and then does the more useful thing: shows precisely where those assumptions fail, because the 1997 Nobel Prize committee gave the award for a model that the market spent the following decades proving wrong in specific, measurable ways.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Branch Prediction</title>
      <link>/posts/branch-prediction/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/branch-prediction/</guid>
      <description>&lt;p&gt;A modern CPU doesn&amp;rsquo;t execute one instruction at a time and wait to see what happens — it runs a deep, multi-stage assembly line called a pipeline, fetching, decoding, and beginning execution on several instructions simultaneously, each at a different stage of completion. That design only works if the pipeline stays full, and roughly one in every three to five instructions in real code is a branch — an if-statement, a loop condition, a function-pointer call — whose outcome the CPU can&amp;rsquo;t actually know until the branch itself finishes executing, several pipeline stages later. Rather than stall the entire pipeline waiting for that answer, the processor guesses which way the branch will go, keeps fetching and speculatively executing instructions down that guessed path, and only finds out later whether the guess was right. Branch prediction is the name for that guess, and it is one of the single largest contributors to how fast modern CPUs actually run real-world code — and, as the 2018 disclosure of Spectre proved, one of the most consequential security assumptions baked into decades of processor design.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cabin Pressurization: The Controlled Leak That Keeps You Alive at 38,000 Feet</title>
      <link>/posts/cabin-pressurization/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cabin-pressurization/</guid>
      <description>&lt;p&gt;A pressurized airliner cabin is not a sealed vessel — it is a controlled leak. Air is pumped in continuously, faster than it needs to escape, and a valve at the back of the fuselage decides exactly how fast that air is allowed to leave. The pressure inside the cabin at 38,000 feet is not a fixed number the airframe was built to hold; it is the output of a live balancing act between an inflow the engines provide almost incidentally and an outflow a computer meters every second of the flight. Get that balance right and passengers breathe comfortably while wearing shorts at an altitude where the outside air would kill them in minutes. Get it wrong — slowly, through a failed seal, or catastrophically, through a structural failure — and the same physics that makes flight possible turns against the people inside it. This is the actual mechanism: where the air comes from, what the outflow valve is really doing, why &amp;ldquo;cabin altitude&amp;rdquo; is a deliberately chosen number well above sea level, and what separates a survivable decompression from a fatal one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Claude Sonnet 5 and Fable 5: The New Generation, Priced and Positioned</title>
      <link>/posts/claude-sonnet-5-and-fable-5-new-generation/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/claude-sonnet-5-and-fable-5-new-generation/</guid>
      <description>&lt;p&gt;Three weeks ago this blog ran the numbers on Fable 5 versus Opus 4.8 and concluded that most interactive work would not notice the difference. Since then, the lineup underneath that analysis has been rebuilt twice. Claude Sonnet 5 launched June 30 at $2 per million input tokens and $10 per million output — introductory pricing, but a third of Opus 4.8&amp;rsquo;s rate card — and closes most of the gap on agentic benchmarks that used to require the expensive model. And Fable 5, the Mythos-class model this blog covered in June, spent 19 days pulled from the market entirely after a jailbreak triggered US export controls, before returning July 1 with a new cybersecurity classifier and a public admission from Anthropic that the tighter guardrails will flag more benign requests.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Concrete and Cement: The Chemistry of Civilization</title>
      <link>/posts/concrete-and-cement-the-chemistry-of-civilization/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/concrete-and-cement-the-chemistry-of-civilization/</guid>
      <description>&lt;p&gt;Concrete does not dry into a solid the way wet clay or plaster does. It reacts into one. When cement powder meets water, a genuine exothermic chemical reaction begins — new crystalline and gel-phase compounds grow directly out of the mixture, interlocking into a stone-like matrix strong enough to hold up a skyscraper — and that reaction is why concrete can cure fully submerged in water, why a concrete pour is rated at a specific 28-day mark rather than &amp;ldquo;once it looks dry,&amp;rdquo; and why the single most-used manufactured material on Earth is also, unavoidably, one of the largest industrial sources of carbon dioxide on the planet. Roughly two-thirds of the world&amp;rsquo;s cement emissions come not from burning fuel but from the chemistry itself — carbon dioxide is a direct reaction product, baked out of limestone, before a single truck ever delivers a load.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creatine, Honestly</title>
      <link>/posts/creatine-honestly/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/creatine-honestly/</guid>
      <description>&lt;p&gt;Creatine has been studied in more controlled trials than almost any other sports supplement, and the accumulated evidence is unusually clean by the standards of nutrition science — which makes it worth separating from the noise around it. Some of that noise is outdated caution (the kidney-damage concern, which never had solid evidence behind it and has since been directly contradicted by long-term data). Some of it is marketing (buffered and hydrochloride forms claiming superiority they haven&amp;rsquo;t demonstrated in head-to-head trials). And some of it is genuine scientific nuance getting flattened into a headline, which is exactly what happened to the recent wave of &amp;ldquo;creatine boosts your brain&amp;rdquo; claims.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Floating Point, Finally</title>
      <link>/posts/floating-point-finally/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/floating-point-finally/</guid>
      <description>&lt;p&gt;Almost every programmer eventually types &lt;code&gt;0.1 + 0.2&lt;/code&gt; into a console and gets back &lt;code&gt;0.30000000000000004&lt;/code&gt;, shrugs, and moves on without ever learning why. The honest answer is that floating point isn&amp;rsquo;t broken — it&amp;rsquo;s doing exactly what its 1985 specification, IEEE 754, defines it to do, and that specification is a deliberate, carefully reasoned trade-off between range, precision, and hardware cost, not an accident. Understanding the actual bit layout underneath a &lt;code&gt;float&lt;/code&gt; or &lt;code&gt;double&lt;/code&gt; explains not just the 0.1-plus-0.2 party trick, but every real numerical bug that has ever shipped because of it — including a 1991 rounding error in a 24-bit military clock register that let a Scud missile through an active Patriot missile defense battery.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Glass: From Sand to Gorilla Glass</title>
      <link>/posts/glass-from-sand-to-gorilla-glass/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/glass-from-sand-to-gorilla-glass/</guid>
      <description>&lt;p&gt;Glass is a solid that never bothered to finish becoming a solid. When silica sand is melted and cooled back down, a crystal — quartz — would normally form as the silicon and oxygen atoms lock into a repeating, orderly lattice. Glass cheats that process: cooled fast enough, the molten material&amp;rsquo;s atoms get too sluggish to find their way into a crystal lattice before the whole mass locks rigid, freezing in place with the same disordered, liquid-like atomic arrangement it had while molten. The result is a genuine physical paradox — a material that is mechanically rigid like a solid but structurally disordered like a liquid, called an amorphous solid — and understanding that one fact explains almost everything interesting about glass as an engineering material: why it&amp;rsquo;s brittle, why it can be made perfectly flat by floating it on liquid metal, and why the glass covering a phone screen and the glass in a windshield are strengthened by the same underlying trick, just executed two different ways.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Glucose and Insulin: The Body&#39;s Control Loop</title>
      <link>/posts/glucose-and-insulin-the-bodys-control-loop/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/glucose-and-insulin-the-bodys-control-loop/</guid>
      <description>&lt;p&gt;Blood glucose regulation is one of the tightest control loops in the human body, and it is worth describing in the vocabulary of control theory rather than biology first, because the biology makes more sense once you see the architecture: a setpoint held in a band roughly 70-100 mg/dL, two antagonistic actuators pushing the signal in opposite directions, a sensing mechanism with a real, measurable lag, and a chronic failure mode — insulin resistance — that degrades actuator gain long before the sensor itself fails. It is such a good control-systems example that engineers eventually built an external controller to replace the biological one when it breaks: a continuous glucose monitor as the sensor, an algorithm running PID or model-predictive control as the controller, and an insulin pump as the actuator, worn on the body as a literal hardware patch for a failed feedback loop. Understanding the native system first is what makes the artificial one legible.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Toilet Actually Works</title>
      <link>/posts/how-a-toilet-actually-works/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-toilet-actually-works/</guid>
      <description>&lt;p&gt;A flush toilet has no pump, no impeller, and no motor, yet it can evacuate a bowl of waste through a trapway narrower than a garden hose in under six seconds. It does this by manufacturing a temporary vacuum out of falling water, using that vacuum to drag everything downstream, and then deliberately killing the vacuum before it can empty the bowl dry. Almost everything interesting about toilet design — the shape of the bowl, the sizing of the tank, the thirty-year fight over how many gallons a flush is allowed to use — traces back to that one self-defeating requirement: create a siphon strong enough to clear the trap, then break it before it clears the water seal that keeps sewer gas out of the house.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Bridges Carry Load</title>
      <link>/posts/how-bridges-carry-load/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-bridges-carry-load/</guid>
      <description>&lt;p&gt;A bridge has exactly one job — move load from a point in space where there&amp;rsquo;s nothing underneath it to a point where there is solid ground — and every bridge design in existence is a different strategy for making sure no single structural member ever has to fight its own material properties to do that job. Steel and steel cable are superb in tension and mediocre in compression when unsupported (they buckle). Concrete and masonry are excellent in compression and nearly useless in tension (they crack). The entire discipline of bridge typology — why some spans are a flat beam on piers, some are a soaring arch, some hang from cables off towers — comes down to how cleverly each design routes force through its members so that tension goes to something good at tension and compression goes to something good at compression. Get that routing wrong, or let it degrade unnoticed, and you get catastrophic failure — which is why the history of bridge engineering is written as much in its failures as its successes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Pain Actually Works</title>
      <link>/posts/how-pain-actually-works/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-pain-actually-works/</guid>
      <description>&lt;p&gt;Pain is not a direct readout of tissue damage. It feels like one — stub a toe, feel pain proportional to the stub — but the actual pipeline between a damaged cell and the conscious experience of hurting has several distinct processing checkpoints, and every one of them can independently amplify, dampen, redirect, or in some cases manufacture a signal with only a loose relationship to what&amp;rsquo;s actually happening in the tissue. Nociception, the raw detection of a potentially damaging stimulus, is only the first stage. What you consciously experience as pain is the output of that signal after it&amp;rsquo;s been filtered through a spinal gate, potentially rerouted by an anatomical coincidence, modulated by descending signals from the brain itself, and — in a meaningful fraction of chronic pain cases — sustained by a nervous system that has changed its own wiring in ways that outlive the injury that triggered them entirely. This is a genuinely engineered-feeling signal-processing pipeline, and understanding each stage explains a set of otherwise strange facts: why rubbing a bumped elbow helps, why a heart attack can feel like a sore left arm, and why &amp;ldquo;it&amp;rsquo;s all in your head&amp;rdquo; is both an insult and, in a narrow technical sense, sometimes almost accurate — just not in the dismissive way it&amp;rsquo;s usually meant.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Touchscreens Work</title>
      <link>/posts/how-touchscreens-work/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-touchscreens-work/</guid>
      <description>&lt;p&gt;The touchscreen on a modern phone doesn&amp;rsquo;t know you touched it. It knows that a small amount of electrical charge disappeared from a specific point on a grid of wires embedded under the glass, and it infers, correctly almost every time, that a finger must have caused it. That inference is the entire trick behind projected-capacitive touch (often abbreviated PCAP), the technology that replaced resistive touchscreens industry-wide after the 2007 iPhone, and understanding it explains three things people run into constantly and rarely think about: why a bare finger works but a cotton glove doesn&amp;rsquo;t, why a wet screen produces phantom taps, and how a phone can track ten simultaneous fingers without any part of the screen physically moving.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Vaccines Train the Immune System</title>
      <link>/posts/how-vaccines-train-the-immune-system/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-vaccines-train-the-immune-system/</guid>
      <description>&lt;p&gt;A vaccine does not fight a pathogen. It has no direct effect on any virus or bacterium at all — everything it does happens before the real threat ever shows up. What a vaccine actually does is exploit a specific, exploitable weakness in how your adaptive immune system learns: the first time it meets a new pathogen, it takes one to two weeks to mount an effective response, because the handful of B and T cells that happen to recognize that exact molecular shape have to be found, expanded, and refined from a starting population that might be a few hundred cells out of trillions. A vaccine runs that entire slow learning process ahead of time, against a piece of the pathogen that can&amp;rsquo;t cause the disease, so that when the real thing arrives the system already has the answer memorized. Understanding vaccines means understanding that learning process — and it turns out to be a genuinely engineered-feeling system: presentation, selection, iterative refinement, and durable storage, each stage with its own failure modes and design trade-offs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Washing Machines Actually Work</title>
      <link>/posts/how-washing-machines-actually-work/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-washing-machines-actually-work/</guid>
      <description>&lt;p&gt;A washing machine is a tuned mechanical resonator carrying a variable mass through its own natural frequency twice per cycle, held together by a concrete block bolted to a stainless drum, spun by a motor whose control loop is more sophisticated than the one flying most consumer drones. Almost nothing about how it works is what the marketing describes. The drum does not &amp;ldquo;clean&amp;rdquo; your clothes; a warm alkaline surfactant solution does, and the drum&amp;rsquo;s job is to keep the fabric moving through that solution while imposing mechanical shear to dislodge trapped soil. The spin cycle is not just fast; it is a controlled excursion through and past the suspension&amp;rsquo;s resonant frequency, timed carefully enough that the machine does not walk out of the laundry room. The direct-drive motor that replaced the belt in the mid-1990s did not appear because belts wear out; it appeared because a variable-frequency BLDC drive gives you enough torque and speed control to solve the load-balance problem that a fixed-ratio belt cannot. And the reason your front-loader smells is not a manufacturing defect — it is a consequence of the exact same door gasket geometry that lets it use a quarter of the water of a top-loader.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LED Bulbs, Really</title>
      <link>/posts/led-bulbs-really/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/led-bulbs-really/</guid>
      <description>&lt;p&gt;An LED light bulb is two separate engineering problems stacked in one glass-and-plastic shell, and almost every consumer complaint about them — flicker, dimmer incompatibility, early failure, harsh color — traces back to only one of those two problems, and it&amp;rsquo;s not the diode. The semiconductor die that actually emits light is close to the most reliable component in the entire assembly, rated for tens of thousands of hours of operation with genuinely gradual, well-characterized decline. The part that breaks, flickers, buzzes, or dies outright is almost always the driver: the small circuit board tucked into the base that converts your wall&amp;rsquo;s 120-volt (or 230-volt) alternating current into the low-voltage, tightly regulated direct current an LED die actually needs to survive. Understanding an LED bulb means understanding those two systems separately, because they&amp;rsquo;re solved by completely different engineering disciplines and they fail for completely different reasons.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mechanical Locks: Pin Tumblers and Why Picking Works</title>
      <link>/posts/mechanical-locks-pin-tumblers-and-why-picking-works/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mechanical-locks-pin-tumblers-and-why-picking-works/</guid>
      <description>&lt;p&gt;A pin tumbler lock is one of the oldest security devices still in daily use in something close to its original form, and it is also, mechanically, a tolerance-stacking problem wearing a security costume. The fact that it can be picked is not a bug introduced by careless manufacturing — it is an unavoidable consequence of the fact that the lock is a physical object built to a tolerance, and any mechanical device built to a tolerance leaks information about its internal state to anyone patient enough to feel for it. Understanding that single fact explains almost everything else about locks: why picking works at all, why &amp;ldquo;security pins&amp;rdquo; are really just false-feedback generators, why a $400 Medeco cylinder changes the game entirely, and why the actual crime data says none of this is what keeps most burglars out of most houses.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Plantar Fasciitis: Mechanics and Evidence-Based Fixes</title>
      <link>/posts/plantar-fasciitis-mechanics-and-evidence-based-fixes/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/plantar-fasciitis-mechanics-and-evidence-based-fixes/</guid>
      <description>&lt;p&gt;Plantar fasciitis is one of the most common reasons people end up limping to a doctor&amp;rsquo;s office, and almost everything about how it gets described is wrong. It is not inflammation — the &amp;ldquo;-itis&amp;rdquo; suffix is a holdover from an assumption that turned out to be false once anyone actually biopsied the tissue. The stretch you were told to do before getting out of bed has weak evidence behind it. The gel insoles, the night splints, the magnetic insole you saw on a late-night infomercial — most of that is either unproven or actively marginal. The intervention with the clearest randomized-trial evidence for actually fixing the underlying problem, rather than just numbing the pain, is loading the tissue heavier than you think a painful tendon-adjacent structure should be loaded.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Huberman Lab Peptides Episode, Reviewed: What Dr. Bakri Said and What Survives Scrutiny</title>
      <link>/posts/huberman-lab-peptides-episode-bakri-reviewed/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/huberman-lab-peptides-episode-bakri-reviewed/</guid>
      <description>&lt;p&gt;On June 1, 2026, the Huberman Lab podcast published a two-hour-forty-eight-minute episode titled &amp;ldquo;Peptides: The Science, Uses &amp;amp; Safety,&amp;rdquo; a guest conversation with Dr. Abud Bakri, a board-certified internal medicine physician who has built a practice and a public following around therapeutic peptides. It is one of the more comprehensive single episodes on the topic to date, moving from BPC-157 through pinealon, epithalon, thymosin alpha-1, GHK-Cu, GLP-1 agonists, retatrutide, growth hormone secretagogues, and melanotan, with side trips into compounding-pharmacy economics, FDA scheduling whiplash, and physician malpractice exposure. As a primary source on what is actually being used, at what doses, and through what supply chains, it is valuable — better sourced and more mechanistically careful than the average grey-market forum thread. As an evidentiary document, it has a structural problem that is worth naming up front: nearly three hours of unhurried, credentialed conversation applies roughly equal narrative weight to a peptide with two completed clinical trials and to one whose entire human evidence base is a podcast host&amp;rsquo;s own self-report from a single night&amp;rsquo;s sleep. Runtime is not rigor. This is a peptide-by-peptide accounting of what the episode claimed, what the underlying literature actually shows, and where the two diverge.&lt;/p&gt;</description>
    </item>
    <item>
      <title>VO2 Max: What It Measures and Whether You Can Change It</title>
      <link>/posts/vo2-max-what-it-measures-and-whether-you-can-change-it/</link>
      <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vo2-max-what-it-measures-and-whether-you-can-change-it/</guid>
      <description>&lt;p&gt;VO2 max is one of the few single numbers in medicine that predicts how long you&amp;rsquo;ll live better than cholesterol, blood pressure, or BMI, and the reason is architectural, not mystical: it doesn&amp;rsquo;t test your heart, your lungs, or your muscles in isolation, it tests the entire oxygen-delivery pipeline end to end, from air entering your lungs to electrons being accepted by mitochondrial enzymes deep inside a muscle cell, and the pipeline&amp;rsquo;s slowest stage sets the ceiling for the whole system. That framing — a serial pipeline with a bottleneck, not a single organ with a score — is also exactly why VO2 max is genuinely trainable in most people and genuinely capped by genetics in ways a 20-week family study has measured with uncomfortable precision. This post covers what the number is, how the lab measures it versus how your watch guesses it, where the physiological bottleneck actually sits, and how much of your ceiling you can move versus how much was decided before you started training.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Elevators Actually Work</title>
      <link>/posts/how-elevators-actually-work/</link>
      <pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-elevators-actually-work/</guid>
      <description>&lt;p&gt;The elevator is statistically the safest way to travel that humans have ever engineered, and it earns that title not through a single clever device but through layers of mechanical paranoia stacked one atop another, each assuming the layer above it has already failed. The cable cannot snap in normal use, but the system is designed as if it will. If it does, a speed-sensing governor trips. If the governor&amp;rsquo;s brake fails, redundant cables share the load. If all of that fails, a buffer waits at the bottom. The popular image of an elevator — a box dangling from a rope over a deadly shaft — is exactly backwards. The box is one of the most over-constrained objects in a building, and the &amp;ldquo;rope&amp;rdquo; was the thing Elisha Otis made safe in 1853 by publicly cutting it on stage and not falling. Understanding how an elevator works is mostly understanding why it refuses to fall even when everything that is supposed to hold it up lets go.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Market Microstructure and Order Books</title>
      <link>/posts/market-microstructure-and-order-books/</link>
      <pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/market-microstructure-and-order-books/</guid>
      <description>&lt;p&gt;The number you see quoted as a stock&amp;rsquo;s &amp;ldquo;price&amp;rdquo; is a polite fiction. There is no single price; there is a list of people willing to buy at various prices, a list of people willing to sell at various prices, and a gap between the best of each. That data structure — the limit-order book — and the deterministic engine that matches orders against it are the actual machinery of modern markets, and almost everything that retail investors find mysterious or sinister about trading (slippage, the spread, &amp;ldquo;the market moved against me the instant I clicked&amp;rdquo;) falls out of understanding it. Market microstructure is the study of how the sausage is made at the level of individual orders and microseconds, and it matters because the gap between the price you saw and the price you got is not random noise. It is the predictable, mechanical cost of interacting with a queue that other people are also fighting over.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vacuum Insulation: The Engineering of a Thermos</title>
      <link>/posts/vacuum-insulation-the-engineering-of-a-thermos/</link>
      <pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vacuum-insulation-the-engineering-of-a-thermos/</guid>
      <description>&lt;p&gt;A good vacuum flask will hold coffee above 70 °C for twelve hours using no power, no moving parts, and a wall thickness of a few millimeters. That is a genuinely remarkable piece of engineering hiding inside a $30 water bottle, and it works because of a single insight: heat moves by exactly three mechanisms, and a thermos is built to sabotage all three simultaneously. Ordinary insulation — foam, fiberglass, a down jacket — only fights one or two of them well and tolerates the rest. The vacuum flask is the rare consumer object that goes after conduction, convection, &lt;em&gt;and&lt;/em&gt; radiation each with a dedicated countermeasure, which is why it outperforms a foam koozie by an order of magnitude despite being thinner. The trade is that the hardest part, the vacuum itself, is invisible, unforgiving, and the thing that eventually fails.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Behavior Trees for Robotics</title>
      <link>/posts/behavior-trees-for-robotics/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/behavior-trees-for-robotics/</guid>
      <description>&lt;p&gt;Ask a roboticist who has shipped an autonomy stack what holds the high-level logic together, and in 2026 the answer is almost always a behavior tree. Not a finite state machine, not a rule engine, not a pile of &lt;code&gt;if&lt;/code&gt; statements in a control loop — a behavior tree, ticked at a fixed rate, deciding moment to moment whether the robot should keep navigating, abandon the goal, clear its costmap, back up, or give up and ask for help. The pattern arrived from game AI, where it organized the enemies in Halo, and it crossed into robotics because it solved a specific, painful problem that finite state machines create the moment a robot has to be &lt;em&gt;reactive&lt;/em&gt;: the explosion of transitions. This post is about why that explosion happens, the formalism that defuses it, how it looks in BehaviorTree.CPP and ROS2 Nav2, and — the part the tutorials skip — where behavior trees are genuinely the right tool and where reaching for them is a mistake.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Homomorphic Encryption Honestly</title>
      <link>/posts/homomorphic-encryption-honestly/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/homomorphic-encryption-honestly/</guid>
      <description>&lt;p&gt;Fully homomorphic encryption is the closest thing modern cryptography has to a magic trick: you hand a server data that it cannot read, the server computes a function on it, hands you back a result it also cannot read, and you decrypt to find the correct answer. No trusted hardware, no splitting the computation across non-colluding parties, no decryption in the middle. The math holds. The catch — and there is always a catch — is that &amp;ldquo;the math holds&amp;rdquo; and &amp;ldquo;this is fast enough to use&amp;rdquo; are separated by three to six orders of magnitude, and closing that gap has been the entire story of the field since Craig Gentry proved it was possible in 2009. In 2026 the honest position is neither &amp;ldquo;FHE changes everything&amp;rdquo; nor &amp;ldquo;FHE is a research toy.&amp;rdquo; It is that FHE has found a handful of narrow, genuinely valuable deployments where the privacy is worth paying for, and remains catastrophically slow for the general case of &amp;ldquo;just run my program on encrypted data.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Anesthesia Works (and Why We Still Can&#39;t Fully Explain It)</title>
      <link>/posts/how-anesthesia-works/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-anesthesia-works/</guid>
      <description>&lt;p&gt;Roughly 300 million people are put under general anesthesia every year, and for most of them it works so reliably that they treat it as a solved problem: you count backward from ten, you reach seven, and then you are in the recovery room with no memory of the intervening hours. It feels like a light switch. It is not. Anesthesia is a controlled, reversible, dose-dependent demolition of consciousness, achieved with drugs whose detailed mechanism we genuinely cannot fully explain. We can predict the dose. We can titrate to effect. We can monitor the brain well enough to keep accidental awareness rare. But if you ask a pharmacologist &lt;em&gt;why&lt;/em&gt; a noble gas with no metabolism and no classical receptor binding can erase your subjective experience, the honest answer is that we have several partial theories and no complete one. This is the rare case in medicine where the practical engineering is far ahead of the underlying science.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Multi-Party Computation in 2026</title>
      <link>/posts/multi-party-computation-in-2026/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/multi-party-computation-in-2026/</guid>
      <description>&lt;p&gt;Secure multi-party computation answers a question that sounds impossible: can a group of mutually distrustful parties jointly compute a function over their private inputs while learning nothing except the output? Two hospitals comparing patient outcomes without revealing patient records; two companies measuring how many of their customers overlap without exchanging customer lists; a thousand phones training a shared model without any phone exposing its data. The theory has existed since the 1980s — Yao&amp;rsquo;s garbled circuits in 1986, the GMW and BGW protocols soon after proved that &lt;em&gt;any&lt;/em&gt; computable function can be evaluated securely — and for almost three decades that theory was a curiosity, because doing it was thousands of times slower than just computing in the clear. The honest story of MPC in 2026 is that it has finally crossed from impossible-in-practice to deployed-in-production, but only inside a narrow envelope, and understanding the shape of that envelope is the whole point.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Cray Era and the Death of the Supercomputer</title>
      <link>/posts/the-cray-era-and-the-death-of-the-supercomputer/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-cray-era-and-the-death-of-the-supercomputer/</guid>
      <description>&lt;p&gt;For roughly twenty years, from the mid-1970s to the mid-1990s, the word &amp;ldquo;supercomputer&amp;rdquo; had a face, and the face belonged to a single man: Seymour Cray. A Cray was a specific kind of machine — a small number of exquisitely hand-tuned vector processors, built from the fastest discrete logic money could buy, cooled by inert liquid because air could not carry the heat away, wired by hand to keep the speed of light from costing it cycles, and priced like a fighter jet. It was the fastest thing in the world at the work that mattered to weapons labs, weather services, oil companies, and aerospace, and for a long stretch nothing else was close. Then, over a single decade, the entire category collapsed. Not because anyone built a better Cray, but because the economics underneath the Cray rotted out from below while nobody at the top was looking.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The History of Computer Graphics</title>
      <link>/posts/the-history-of-computer-graphics/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-history-of-computer-graphics/</guid>
      <description>&lt;p&gt;Every frame your machine draws is an answer to a physics question it cannot actually solve. Light bounces around a scene an unbounded number of times, scattering off surfaces according to material functions that depend on every other surface, and the brightness of a single pixel is, in full generality, an infinite recursive integral. James Kajiya wrote that integral down formally in 1986, and the entire history of computer graphics, both before and after, is the history of dodging it: approximating it, sampling it, baking it, faking it, and eventually building dedicated silicon to evaluate one term of it fast enough to do sixty times a second. The field advances along two axes that constantly trade against each other, physical correctness and time budget, and almost every famous result in graphics is a clever point on that trade-off curve. This is the story of how we got from a light pen scratching lines on a vector scope in 1963 to GPUs that fire billions of rays per second and then hand the noisy result to a neural network to clean up, and why, even now, &amp;ldquo;real-time path tracing&amp;rdquo; is still a polite lie held together by denoisers and upscalers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Internet&#39;s Founding RFCs</title>
      <link>/posts/the-internets-founding-rfcs/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-internets-founding-rfcs/</guid>
      <description>&lt;p&gt;The most consequential technical documents of the twentieth century were not patents, standards, or specifications handed down by a committee with subpoena power. They were memos. Numbered, plaintext, often apologetic memos called Requests for Comments, the first of which was written in April 1969 by a graduate student so worried about overstepping his authority that he chose the deferential name on purpose. From that anxious first note grew a corpus of more than nine thousand documents that collectively define the protocols every connected device on Earth speaks, and — more importantly — a culture of design that explains why the internet is decentralized, robust, and effectively impossible to switch off. To understand why the internet works the way it does, you read the founding RFCs: RFC 1, which established the tone; RFC 791 and RFC 793, which established the protocols; and the April Fools&amp;rsquo; joke RFC 1149, which, by specifying how to carry internet traffic on pigeons, accidentally explained the entire architecture better than any textbook.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Lisp Story</title>
      <link>/posts/the-lisp-story/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-lisp-story/</guid>
      <description>&lt;p&gt;Lisp is the second-oldest programming language still in use, and it has spent most of its sixty-eight years being simultaneously ahead of its time and commercially marginal. John McCarthy did not set out to design a practical language; he was trying to write down a clean mathematical notation for symbolic computation, and the language fell out of the notation almost by accident. That origin explains nearly everything strange and durable about Lisp: its parenthesized syntax is a direct consequence of representing programs as data, its evaluation model was specified as a short recursive function before any compiler existed, and its commercial history is a long sequence of brilliant systems that lost to cheaper, dumber hardware. The remarkable thing is not that Lisp failed to take over the world. It is that almost every idea Lisp pioneered — garbage collection, the read-eval-print loop, first-class functions, closures, dynamic typing with late binding, conditional expressions, and metaprogramming through macros — quietly took over the world anyway, embedded in languages that look nothing like Lisp. This is the story of how that happened, who paid for it, and why a sixty-year-old idea keeps coming back.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Modular Monolith</title>
      <link>/posts/the-modular-monolith/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-modular-monolith/</guid>
      <description>&lt;p&gt;Somewhere around 2015 the industry collectively decided that the monolith was the enemy, and for the better part of a decade the reflexive answer to almost any scaling, velocity, or team-coordination problem was the same: split it into microservices. The advice was wrong for most of the teams who took it, and the reason it was wrong is not subtle. The thing those teams actually wanted was &lt;em&gt;modularity&lt;/em&gt; — clear boundaries between parts of the system, the ability to reason about one piece without dragging in the whole, the freedom to change the inventory code without breaking checkout. Microservices deliver modularity, but they bundle it with a tax that has nothing to do with modularity and everything to do with the network: every method call becomes a remote call that can hang, time out, or partially fail; every transaction that used to commit atomically becomes a choreography of compensations; every &amp;ldquo;where did this request go&amp;rdquo; becomes a distributed-tracing project. You can have modularity without paying that tax. The architecture that gives it to you is the modular monolith, and the honest version of the last decade is that most of the rewrites should never have happened.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Personal Computer Wars</title>
      <link>/posts/the-personal-computer-wars/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-personal-computer-wars/</guid>
      <description>&lt;p&gt;The personal computer wars were not won by the best machine, the best company, or the best idea. They were won, almost by accident, by a set of architectural decisions made under deadline pressure in 1980 and 1981 — decisions whose consequences nobody at the time fully understood and which IBM, the company that made most of them, spent the next decade trying and failing to undo. The IBM PC was assembled in roughly a year out of off-the-shelf parts, documented in a published technical reference manual, built around an open expansion bus, and shipped with an operating system that IBM licensed but did not own exclusively. Each of those choices was rational given the goal — ship a credible personal computer fast and cheap. Together they created something IBM never intended: a &lt;em&gt;platform&lt;/em&gt; that anyone could clone, extend, and improve, and whose value accrued not to the hardware maker but to the two suppliers who controlled the parts everyone needed to be compatible with — Intel&amp;rsquo;s instruction set and Microsoft&amp;rsquo;s operating system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Science of Muscle Hypertrophy: Tension, Volume, and the Folklore</title>
      <link>/posts/the-science-of-muscle-hypertrophy/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-science-of-muscle-hypertrophy/</guid>
      <description>&lt;p&gt;Muscle is the most adaptable tissue you own, and the rules for growing it are simpler and more boring than the supplement industry would like you to believe. A muscle gets bigger when you repeatedly force its fibers to produce high tension, eat enough protein and total energy to build with, and let it recover — and almost everything else marketed as essential is either a small modifier or pure folklore. The frustrating part is that the &lt;em&gt;mechanism&lt;/em&gt; is genuinely subtle: a mechanical force at the cell membrane gets converted into a chemical signal that ends with ribosomes assembling new contractile proteins, and the field spent two decades arguing about which part of &amp;ldquo;lifting weights&amp;rdquo; actually triggers it. The good news is that the practical conclusions have converged hard in the last ten years. This is a walk from the molecule up to the program, marking the line between what the evidence supports and what is bro-science the whole way.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of BlackBerry</title>
      <link>/posts/the-story-of-blackberry/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-blackberry/</guid>
      <description>&lt;p&gt;For about ten years, the most important computer in the world was not on a desk. It was a black plastic slab with a thumb keyboard, clipped to the belt of a banker, a lawyer, a cabinet minister, or a White House staffer, and it buzzed when email arrived because the email had been &lt;em&gt;pushed&lt;/em&gt; to it — not fetched, not polled, but delivered the instant it landed on a corporate mail server halfway across the planet. Research In Motion did not invent the smartphone, and it did not invent email, but it was the first company to make mobile email feel instantaneous, secure, and effortless on the slow, metered, unreliable cellular networks of the early 2000s. That single trick — reliable push over expensive 2G data, wrapped in cryptography that governments trusted — built an empire. It also built a trap. RIM&amp;rsquo;s entire architecture, its business model, and its institutional identity were optimized for a world of keyboards, network operations centers, and IT departments that bought devices in bulk. When the iPhone arrived in 2007 and redefined the phone as a general-purpose touchscreen computer running third-party apps, RIM did not freeze out of laziness. It was disrupted because the thing it was best in the world at suddenly stopped mattering. This is the story of how that happened, and what was left standing afterward.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Chicken Scheme</title>
      <link>/posts/the-story-of-chicken-scheme/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-chicken-scheme/</guid>
      <description>&lt;p&gt;Most programming languages that survive twenty-five years do so by getting big: a corporate sponsor, a package registry with a hundred thousand entries, a conference circuit, a foundation with a budget. CHICKEN Scheme survived by getting small and staying honest about it. It is a Scheme implementation written largely by one man, Felix Winkelmann, beginning around the year 2000, built on a single sharp technical idea — compile Scheme to portable C and let the system&amp;rsquo;s existing C compiler do the heavy lifting — and that one decision rippled outward into everything that made CHICKEN useful: trivial portability to anything with a C compiler, a foreign-function interface so direct it feels like cheating, native executables small enough to drop onto embedded hardware, and a garbage collector borrowed from a gloriously strange 1994 paper by Henry Baker. CHICKEN never threatened Python, never threatened JavaScript, never even threatened its larger Scheme cousins Racket and Guile. It did not need to. It found a niche — system scripting, glue code, embedded targets, the unglamorous infrastructure layer of Linux boxes — and it served that niche faithfully for a quarter century with a community you could fit in a large room. This is the story of that implementation: the technical thesis that defined it, the ecosystem that grew around it, and what a small-but-real language teaches us about survival when the gravity wells of the industry are pulling everything else toward the center. If you want to actually install it and write code, the companion &lt;a href=&#34;/posts/chicken-scheme-practical-guide/&#34;&gt;practical guide&lt;/a&gt; is the place to start; this post is the history.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Gentoo</title>
      <link>/posts/the-story-of-gentoo/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-gentoo/</guid>
      <description>&lt;p&gt;Most Linux distributions hand you a finished operating system: someone else decided which features to compile in, which optional dependencies to link against, and which compiler flags to use, then shipped you the resulting binaries. Gentoo refused to make those decisions for you. It shipped a &lt;em&gt;framework&lt;/em&gt; — a build system, a package tree of recipes, and a configuration language — and asked you to compile the entire system from source on your own machine, against your own choices, for your own CPU. The result was simultaneously the most flexible Linux distribution ever built and the most famous time-sink in open-source folklore. Gentoo gave the world the USE flag, the idea that a single configuration toggle could conditionally recompile features across thousands of packages at once; it gave the world Portage, a package manager written in Python that treated software builds as a dependency graph to be solved rather than a tarball to be unpacked; and it gave the world a documentation handbook so good that people who never ran Gentoo learned how Linux fits together by reading it. It also gave the world the &amp;ldquo;Gentoo ricer&amp;rdquo; meme — the user who spends three days compiling Firefox with &lt;code&gt;-march=native&lt;/code&gt; to gain a performance difference they cannot measure. Both halves of that reputation are deserved. This is the story of how a developer named Daniel Robbins built a distribution around the conviction that &lt;em&gt;you&lt;/em&gt; should be the integrator, why that conviction mostly lost to binary distributions on the metric of time, and why it nonetheless persists — genuinely, defensibly — in embedded systems, hardened minimal builds, ChromeOS, and the homelab of anyone who wanted to know exactly what their computer was doing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Java</title>
      <link>/posts/the-story-of-java/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-java/</guid>
      <description>&lt;p&gt;Java is the most successful programming language almost nobody set out to build. It was designed in the early 1990s for interactive television and set-top boxes — a market that did not exist and did not materialize for another fifteen years. It pivoted to the web at exactly the moment the web was being invented, rode the dot-com boom into every bank and insurance company on earth, became the default language of computer science education for two decades, and then, in a final twist nobody planned, became the foundation of Android and therefore the most-deployed application platform in human history. None of that was the original plan. The plan was to make toasters and cable boxes talk to each other. The thing that survived all of those pivots, the thing that is actually the story, is not the syntax. It is the &lt;strong&gt;Java Virtual Machine&lt;/strong&gt;: a portable abstract computer with a defined bytecode, a verifier, a just-in-time compiler, and a garbage collector, whose architecture became so influential that Microsoft cloned the whole idea wholesale for .NET, and whose existence turned out to matter far more than the language that shipped on top of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of MS-DOS and Windows</title>
      <link>/posts/the-story-of-ms-dos-and-windows/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-ms-dos-and-windows/</guid>
      <description>&lt;p&gt;The most consequential operating system of the personal-computer era was not designed; it was purchased, in a hurry, for almost nothing, by a company that did not write it and barely understood what it had. In the summer of 1980 Microsoft did not have an operating system. By the end of 1981 it had licensed one to IBM, watched it ship on the IBM PC, and quietly retained the right to sell that same OS to everyone else — a contractual detail that would make it richer than IBM and outlast IBM entirely in the PC business. The operating system was MS-DOS, and it was a knockoff of a knockoff: a 16-bit reimplementation of an 8-bit OS called CP/M, written by a third party in a few months, bought by Microsoft for a flat fee. From that unglamorous start grew a forty-five-year arc that runs through the 640K barrier and its baroque workarounds, through Windows as a flimsy graphical shell bolted onto DOS, through the unification of consumers and engineers on Windows 95, through a parallel-universe period when Microsoft shipped two entirely different operating systems that happened to share an API, and finally to the moment when the clean engineering won and the consumer line was quietly euthanized. The throughline is not technical elegance — DOS and the 9x line were held together with tape and prayer — but a relentless, almost pathological commitment to backward compatibility that turned a stable application binary interface into the most durable moat in the history of software. This is the story of how that happened.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Perl</title>
      <link>/posts/the-story-of-perl/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-perl/</guid>
      <description>&lt;p&gt;For roughly a decade — call it 1994 to 2004 — Perl was the most important programming language in the world that nobody talks about anymore. It was the duct tape of the early internet, the language a majority of dynamic web pages were generated in before PHP and Rails existed. It was the sysadmin&amp;rsquo;s pocketknife, the thing you reached for when &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;awk&lt;/code&gt; ran out of road but you did not want to write C. It was the language the Human Genome Project ran on, the glue that held bioinformatics together during the years the genome was actually being sequenced. It had the single best idea in language tooling for fifteen years — CPAN, a comprehensive, searchable, tested archive of reusable modules — built and battle-tested long before PyPI, RubyGems, or npm were even sketches. And then, at the absolute peak of its powers, the community announced a complete rewrite, spent fifteen years building it, and in the waiting froze the language that was actually paying the bills. By the time the dust settled, the web had moved to PHP and then Ruby and then JavaScript, the scripting crown had passed to &lt;a href=&#34;/posts/the-story-of-python/&#34;&gt;Python&lt;/a&gt;, and Perl was a language you maintained rather than a language you chose.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of SQL</title>
      <link>/posts/the-story-of-sql/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-sql/</guid>
      <description>&lt;p&gt;SQL is the most successful programming language nobody decided to design. It was not the product of a committee chasing elegance, nor a startup chasing a market; it fell out of a math paper an IBM researcher wrote to settle an argument about how data should be stored, and then it survived fifty years of people insisting it was about to die. It outlived the network databases that ruled the 1970s, the object databases that were going to replace it in the 1990s, and the NoSQL stores that promised &amp;ldquo;web scale&amp;rdquo; in the 2000s. The remarkable thing is not that SQL won once. It is that it kept winning against successive generations of engineers who were absolutely certain they had found something better, and who then, with impressive regularity, bolted a SQL interface onto their replacement. This is the story of why a declarative language built on relational algebra proved so durable, where it genuinely lost ground, and why the counter-revolution mostly marched back home.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of TeX and LaTeX</title>
      <link>/posts/the-story-of-tex-and-latex/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-tex-and-latex/</guid>
      <description>&lt;p&gt;In 1977 Donald Knuth received the galley proofs for the second edition of the second volume of &lt;em&gt;The Art of Computer Programming&lt;/em&gt; and found them ugly. The first edition had been set in hot metal by a Monotype machine; the new one had been phottypeset by a digital process, and the mathematics looked wrong — the spacing was off, the symbols were misshapen, the whole page lacked the density and balance of real typography. For most authors this would have been a complaint to the publisher. For Knuth it was the start of a side project that consumed roughly a decade of his life, produced two complete software systems and a new methodology for writing programs, and ended up underwriting the entire apparatus of mathematical and scientific publishing for the next half century. He thought it would take six months. It took ten years.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Ubuntu</title>
      <link>/posts/the-story-of-ubuntu/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-ubuntu/</guid>
      <description>&lt;p&gt;Ubuntu is the strangest kind of success story: a distribution that lost nearly every architectural war it picked and won the only one that turned out to matter. Canonical bet on the Upstart init system and was beaten by systemd. It bet on the Mir display server and was beaten by Wayland. It bet on the Unity desktop, alienated a chunk of its own community for seven years, and then capitulated back to GNOME. It bet that phones, tablets, and PCs would converge on a single Ubuntu image and shipped a phone almost nobody bought. By any reasonable scorecard of its public technical gambles, Ubuntu is a graveyard of dead projects. And yet when you spin up an instance on AWS, Azure, or GCP, the default Linux is overwhelmingly Ubuntu. When a developer types &lt;code&gt;wsl --install&lt;/code&gt; on Windows, they get Ubuntu. When a Docker base image is pulled billions of times, a huge share of them say &lt;code&gt;FROM ubuntu&lt;/code&gt;. The distribution that could not win the desktop it was founded to conquer quietly became the substrate that the entire modern software industry develops, builds, and deploys on. This is the story of how a man who made his fortune selling certificates and then flew to space spent a decade and a fortune chasing the wrong prize, and stumbled into the right one. It begins, as all Ubuntu stories do, with Debian.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vehicle-to-Grid (V2G) Honestly</title>
      <link>/posts/vehicle-to-grid-v2g-honestly/</link>
      <pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vehicle-to-grid-v2g-honestly/</guid>
      <description>&lt;p&gt;There are roughly forty kilowatt-hours of usable battery in a base Nissan Leaf and well over a hundred in a Ford F-150 Lightning, and most of the time that energy sits in a parked car doing nothing. Multiply by the tens of millions of EVs now on the road and you get a number that makes grid planners dizzy: a distributed battery measured in terawatt-hours, already paid for by someone else, scattered across exactly the residential feeders where evening demand peaks. Vehicle-to-grid is the idea that you let the grid borrow some of it — charge when power is cheap and abundant, discharge back when it is scarce and expensive, and pay the car&amp;rsquo;s owner for the service. It is a genuinely good idea, the physics works, and in 2026 it is still mostly not happening at your house.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI-Assisted Coding: The Complete Developer&#39;s Guide to Tools, Agents, and Local Models</title>
      <link>/posts/ai-assisted-coding/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ai-assisted-coding/</guid>
      <description>&lt;p&gt;The way we write software is changing faster than at any point in the last two decades. In 2022, AI coding tools were novelty autocomplete engines. By 2026, they are autonomous agents capable of planning features, writing multi-file implementations, running tests, and iterating on failures — all without direct intervention. This post maps the full landscape: the agentic IDEs, the protocol that connects AI to your tools, the cloud coding assistants, and how to run everything privately on your own hardware.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Audio Latency Honestly</title>
      <link>/posts/audio-latency-honestly/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/audio-latency-honestly/</guid>
      <description>&lt;p&gt;Latency is the one audio number that everybody quotes and almost nobody adds up correctly. A converter&amp;rsquo;s spec sheet brags about &amp;ldquo;1.2 ms round-trip,&amp;rdquo; a plugin developer reports &amp;ldquo;0 samples latency,&amp;rdquo; a wireless in-ear system claims &amp;ldquo;less than 4 ms&amp;rdquo; — and a guitarist still complains that monitoring through the desk feels like playing underwater. The reason is that latency is not a property of any single box. It is the sum of every conversion, buffer, transport hop, DSP block, and meter of air the signal crosses on its way from the source to an ear, and the human nervous system reacts to the &lt;em&gt;total&lt;/em&gt;, not to the most flattering line item. The honest way to think about audio latency is as a budget you spend down a chain, with a hard perceptual ceiling at the end of it, and the engineering job is knowing which links cost what so you can cut the expensive ones without breaking everything else.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Backup Strategy in Practice: Restic, Backblaze B2, rclone, and Actually Testing Restores</title>
      <link>/posts/backup-strategy/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/backup-strategy/</guid>
      <description>&lt;p&gt;Most people set up backups after their first data loss. That is the wrong order.&lt;/p&gt;&#xA;&lt;p&gt;The hard part is not the tooling — the tooling is excellent and mostly free. The hard part is convincing yourself, before anything bad happens, that the hour spent configuring and testing a backup system is worth more than the hour spent building the next feature, adding the next service, or doing anything else that feels more immediately productive. It is. By a large margin.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BGP Hijacks and RPKI: From Origin Validation to Path Security</title>
      <link>/posts/bgp-hijacks-and-rpki/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bgp-hijacks-and-rpki/</guid>
      <description>&lt;p&gt;The Border Gateway Protocol moves every packet on the internet between networks, and its trust model is one sentence long: whoever announces a route is presumed to own it. There is no signature, no proof, and historically no check. When Pakistan Telecom announced YouTube&amp;rsquo;s address block to the world in 2008 to censor it domestically, the announcement leaked upstream and YouTube vanished from the internet for two hours — not because anyone broke in, but because the global routing table did exactly what it was designed to do: believe the most specific announcement it heard. Twelve years later a Rostelecom leak in 2020 briefly pulled traffic for Google, Amazon, Cloudflare, and a hundred other networks through Russia. The mechanics never changed. What changed is that we finally have a deployed, cryptographic way to make routers ask &amp;ldquo;are you actually allowed to originate this?&amp;rdquo; — and a real, measurable fraction of the internet now asks it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CI/CD Pipelines in 2026: The Merge Gate, the Deploy Strategy, and the Supply Chain</title>
      <link>/posts/ci-cd-pipelines/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ci-cd-pipelines/</guid>
      <description>&lt;p&gt;&amp;ldquo;Set up a CI/CD pipeline&amp;rdquo; usually produces a YAML file that runs the tests and then SSHes somewhere to copy files. That works until the day a broken build reaches production, a deploy takes the site down with no way back, or a compromised dependency ships straight through your automation. The value of a pipeline was never in the syntax — it is in two things the quick tutorials gloss over: the &lt;strong&gt;merge gate&lt;/strong&gt; that keeps your main branch always shippable, and the &lt;strong&gt;deployment strategy&lt;/strong&gt; that makes releasing a non-event. CI and CD are genuinely different disciplines, and most teams are good at one and weak at the other. This is how to do both, plus the supply-chain hardening that 2026 made non-optional.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Container Security in 2026: The Threat Model, the Supply Chain, and a Pod That Can&#39;t Hurt You</title>
      <link>/posts/container-security/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/container-security/</guid>
      <description>&lt;p&gt;A virtual machine has its own kernel and a hardware-enforced boundary; if a process escapes the guest OS it still has to defeat the hypervisor. A container has none of that. Every container on a host shares the host&amp;rsquo;s single Linux kernel, and &amp;ldquo;isolation&amp;rdquo; is just a set of kernel features — namespaces, cgroups, capabilities — that the kernel can be talked out of enforcing. That is the one fact the rest of container security follows from: &lt;strong&gt;a default container is not a security boundary, it is a packaging format with some isolation bolted on.&lt;/strong&gt; The good news is that with a dozen specific settings you can make a container behave like a real boundary. The bad news is that almost nobody applies them, and the defaults are permissive. This is the practical version of getting it right.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Modern Helicopter Works</title>
      <link>/posts/how-a-modern-helicopter-works/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-modern-helicopter-works/</guid>
      <description>&lt;p&gt;A fixed-wing aircraft borrows the runway to make its wing work. It accelerates down a strip of concrete until the air moving over the wing is fast enough to lift the whole machine, and from then on the engine&amp;rsquo;s job is mostly to keep that airflow coming. A helicopter refuses the bargain. It carries its runway with it, in the form of a wing it spins in a circle, and it pays for that freedom with a control problem so vicious that for the first forty years of powered flight nobody could solve it. Every part of a modern helicopter that looks baroque — the nest of links under the rotor, the little propeller stuck on the tail, the way the whole disc tilts when the pilot moves a stick — is the residue of that problem being beaten into submission. Understanding the machine means understanding the fight.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Modern HVAC System Works</title>
      <link>/posts/how-a-modern-hvac-system-works/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-modern-hvac-system-works/</guid>
      <description>&lt;p&gt;The thermodynamic heart of every air conditioner, heat pump, and refrigerator is the same vapor-compression refrigeration cycle, and it is genuinely worth understanding on its own terms — but it is also, by now, a solved and boring problem. The compressor, the two coils, and the expansion valve have worked the same way for ninety years. The engineering that actually distinguishes a good modern HVAC system from a bad one, and a $4,000 install from a $14,000 one, lives almost entirely in the parts wrapped &lt;em&gt;around&lt;/em&gt; that cycle: how finely the compressor can modulate its output, how intelligently the thermostat and the equipment talk to each other, whether the ductwork can actually move the air the equipment is trying to push, and which overall system topology you chose for the building. Those four decisions determine your comfort, your energy bill, and your repair headaches far more than the brand on the condenser.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Google Was Built</title>
      <link>/posts/how-google-was-built/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-google-was-built/</guid>
      <description>&lt;p&gt;Google&amp;rsquo;s lasting contribution to engineering is not the search box. It is a stack of roughly a dozen research papers, published between 2003 and 2012, that took the messy, expensive, vendor-locked world of &amp;ldquo;big iron&amp;rdquo; reliability and replaced it with a single radical bet: build your fault tolerance in &lt;em&gt;software&lt;/em&gt;, run it on the cheapest hardware you can buy, and assume every component is constantly failing. That bet — and the systems that implemented it — is why the modern data center looks the way it does. Hadoop is a clean-room reimplementation of two Google papers. Kubernetes is Borg with the serial numbers filed off. HBase and Cassandra are Bigtable&amp;rsquo;s children. CockroachDB and TiDB chase Spanner. The remarkable thing is that Google told everyone how it worked, in detail, for free, and the rest of the industry spent fifteen years catching up. This post traces the lineage of those decisions, the engineering inside each layer, and the honest trade-offs — including the most important one, which is that you are almost certainly not Google and should not pretend to be.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How TCP/IP Actually Won</title>
      <link>/posts/how-tcp-ip-actually-won/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-tcp-ip-actually-won/</guid>
      <description>&lt;p&gt;By the early 1980s, almost every serious person in networking believed the future belonged to OSI. Governments mandated it. Standards bodies poured a decade of committee work into it. Textbooks taught its seven layers as gospel, and they still do. Telecom incumbents — the people who actually owned the wires — backed it. TCP/IP, by contrast, was a research-network protocol family designed by a handful of academics and defense contractors, running on a network most of the planet had never heard of. And yet, by the mid-1990s, OSI was effectively dead on the wire and TCP/IP carried everything. This was not an accident, and it was not luck. TCP/IP won because of a specific set of architectural bets and cultural choices: a connectionless datagram model that pushed complexity to the edges, a development process that valued running code over paper standards, and — decisively — a free, working reference implementation that shipped on the exact machines researchers were already using. OSI lost not because its ideas were bad, but because it tried to design the network the way a phone company designs a switch: completely, correctly, and far too late.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTP/3 and QUIC in Production</title>
      <link>/posts/http3-and-quic-in-production/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/http3-and-quic-in-production/</guid>
      <description>&lt;p&gt;QUIC turned five years old in May 2026, and the protocol is past the phase where it was a curiosity. Every major CDN runs it by default, every browser negotiates it without asking, and about a third of traffic on Cloudflare&amp;rsquo;s edge speaks it on any given day. The decision in 2026 is not whether HTTP/3 is real but whether your particular origins, load balancers, and middle-network are ready for a transport that runs over UDP, encrypts almost every observable bit, and behaves nothing like TCP under monitoring. The honest picture is that HTTP/3 ships real wins on the long tail of bad connections, costs more CPU on the server, breaks infrastructure people forgot they owned, and fails silently when it does break.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTPS and TLS Explained: The Handshake, the Certificates, and a Config That Scores A&#43;</title>
      <link>/posts/https-tls-explained/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/https-tls-explained/</guid>
      <description>&lt;p&gt;Every site needs HTTPS, and most engineers can wire up &lt;code&gt;certbot&lt;/code&gt; in five minutes. The problem is what they copy along with it: handshake explanations that describe a protocol nobody has negotiated since 2018, an Nginx directive that logs a deprecation warning on every reload, and a &amp;ldquo;security headers&amp;rdquo; block whose first entry is a header browsers deleted years ago — one that can actively &lt;em&gt;introduce&lt;/em&gt; the vulnerability it claims to stop. TLS is the most successful security protocol ever deployed, and the tooling around it is genuinely excellent. The advice surrounding it has rotted. This is what a correct, current setup looks like and why each piece is there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Image Codecs Compared</title>
      <link>/posts/image-codecs-compared/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/image-codecs-compared/</guid>
      <description>&lt;p&gt;The question &amp;ldquo;which image codec is best&amp;rdquo; has no answer, because the modern formats were built for different battles and the one that wins a benchmark frequently loses the war that actually matters: adoption. AVIF can beat JPEG by half the file size and still be the wrong choice for a photographer&amp;rsquo;s archive; JPEG XL can be the most technically elegant format in the field and still be undeliverable to most of the web because one browser vendor pulled it. HEIC is on a billion phones and almost no web pages. The honest comparison is not a single leaderboard but a matrix of three independent axes — compression efficiency, feature support, and licensing — where the third axis quietly overrules the first two. A format that compresses 20 percent better than its rival but carries a patent pool the browser makers refuse to license is, for web purposes, the worse format. That is the uncomfortable lesson of the last decade of image coding, and it is exactly the same dynamic that played out in &lt;a href=&#34;/posts/audio-codecs-compared/&#34;&gt;audio codecs&lt;/a&gt;, where the royalty-free option won distribution even when it was not the cleanest compressor.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Infrastructure as Code in 2026: Terraform, OpenTofu, and the State You Have to Manage</title>
      <link>/posts/infrastructure-as-code/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/infrastructure-as-code/</guid>
      <description>&lt;p&gt;Infrastructure as code is the practice of describing your servers, networks, databases, and DNS records in version-controlled text files, then having a tool reconcile reality to match that description. It replaces the console-clicking, the tribal knowledge, and the &amp;ldquo;don&amp;rsquo;t touch that instance, nobody knows how it was set up&amp;rdquo; with a repository you can diff, review, and replay. That much has been settled for a decade. What has &lt;em&gt;not&lt;/em&gt; been settled — and what makes writing about IaC in 2026 different from writing about it in 2021 — is two things the introductory tutorials still skip. First, the most popular tool in the space, Terraform, is no longer open source, and its open-source fork OpenTofu is now a serious, independently-governed project that thousands of teams have migrated to. Second, the genuinely hard part of IaC was never the syntax; it is the &lt;strong&gt;state file&lt;/strong&gt;, the tool&amp;rsquo;s model of what it believes exists, and almost every painful IaC incident traces back to state drifting from, corrupting against, or disagreeing with reality. This post is the foundation: the declarative model, the licensing landscape you have to choose within, real configuration, and the operational truths that decide whether IaC makes your life better or gives you a new and exciting way to delete production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>KV Cache Engineering: PagedAttention, Continuous Batching, Attention Variants, and the Bandwidth Wall</title>
      <link>/posts/kv-cache-optimization/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kv-cache-optimization/</guid>
      <description>&lt;p&gt;The KV cache is responsible for more wasted GPU memory in LLM serving than any other single factor. Before PagedAttention, systems pre-allocated memory for the maximum possible sequence length for every request — even short conversations claimed the same memory footprint as the longest possible output. That pattern wasted 60–80% of GPU memory that could have been used to serve more concurrent requests.&lt;/p&gt;&#xA;&lt;p&gt;Understanding the KV cache is not optional if you&amp;rsquo;re running or building LLM inference infrastructure. It determines how many concurrent requests you can serve, how long your contexts can be, what batch sizes are achievable, and whether prefix caching is giving you the 10× cost reduction it promises or producing a 2% hit rate that helps nobody.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Networking Fundamentals</title>
      <link>/posts/linux-networking-fundamentals/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-networking-fundamentals/</guid>
      <description>&lt;p&gt;Networking is central to Linux administration, and it is also one of the things developers most often treat as a black box until something breaks. This guide covers both halves: the protocol concepts every developer should carry in their head — the TCP/IP model, IP addressing, CIDR math, TCP vs. UDP, ports, and NAT — and the Linux commands and config files that configure, monitor, and troubleshoot real networks.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-networking-model-layers-addresses-and-protocols&#34;&gt;The Networking Model: Layers, Addresses, and Protocols&lt;/h2&gt;&#xA;&lt;p&gt;Before the commands, the mental model. Almost every network problem you will ever debug lives at one of four layers, and knowing which layer narrows the search enormously.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LLM Quantization Compared: GGUF, AWQ, GPTQ, FP8, and the int4 Cliff</title>
      <link>/posts/llm-quantization-compared/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/llm-quantization-compared/</guid>
      <description>&lt;p&gt;A 70-billion-parameter model in 16-bit weights needs 140 GB just to hold the parameters, before a single token of context. Quantize those weights to 4 bits and the same model fits in roughly 40 GB — one card instead of two, a consumer GPU instead of a datacenter one, a model that runs at all instead of one that swaps to disk and dies. That is why quantization is not an optimization you reach for late; for anyone running models outside a hyperscaler it is the thing that decides what you can run at all. The catch is that &amp;ldquo;4-bit&amp;rdquo; is not one technique. GGUF, GPTQ, AWQ, and FP8 make different bets about &lt;em&gt;what&lt;/em&gt; to compress, &lt;em&gt;how&lt;/em&gt; to choose the rounding, and &lt;em&gt;where&lt;/em&gt; the quality goes when it goes. This is what each one actually does and how to pick.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modern Tire Pressure Monitoring Systems: The Engineering Behind the Most-Ignored Light</title>
      <link>/posts/modern-tire-pressure-monitoring-systems/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-tire-pressure-monitoring-systems/</guid>
      <description>&lt;p&gt;The little horseshoe-with-an-exclamation-point is the most-ignored warning on the modern dashboard, and the one drivers understand least. People treat it like a suggestion, drive on it for months, and assume it means &amp;ldquo;add some air eventually.&amp;rdquo; Behind that dismissed glyph sits one of the more quietly impressive embedded systems on the car: a sealed, potted electronics package, smaller than a key fob, that has to measure pressure and temperature accurately, transmit them over radio, survive a decade of -40 to +125°C swings and hundreds of g of centrifugal load while bolted to a wheel spinning at 1,000 rpm — all on a single lithium battery it can never recharge and a designer can never replace. It exists because of a body count: a wave of rollover deaths at the turn of the millennium that Congress responded to with a law. Understanding TPMS means understanding a regulation written in blood, two completely different engineering philosophies for solving the same problem, a radio-frequency standards mess that makes parts a nightmare, and the relearn procedure that explains why your light won&amp;rsquo;t turn off after a tire shop visit. None of it is the throwaway feature the dashboard icon implies.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modern Video Codecs</title>
      <link>/posts/modern-video-codecs/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-video-codecs/</guid>
      <description>&lt;p&gt;The video codec that wins is almost never the one that compresses best. It is the one that clears two bars the spec sheet does not mention: a patent-licensing regime cheap and predictable enough that device makers will ship it, and a hardware decoder in enough silicon that playback does not melt the battery. HEVC is roughly half the bitrate of H.264 at the same quality and has spent a decade as the format the open web refuses to touch, because its licensing fragmented into competing royalty pools no one could safely pay. AV1 is not dramatically better than HEVC on pure efficiency, yet Google, Netflix, Meta, and Amazon bet the future of streaming on it for one reason: it is royalty-free. The honest study of modern video codecs is therefore not a compression leaderboard. It is the interaction of three forces — rate-distortion efficiency, hardware support, and licensing — where the second and third routinely overrule the first.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Plywood, MDF, OSB, and Solid Wood Honestly</title>
      <link>/posts/plywood-mdf-osb-and-solid-wood-honestly/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/plywood-mdf-osb-and-solid-wood-honestly/</guid>
      <description>&lt;p&gt;Walk into any home center and you will find four materials sold side by side, in the same 4×8 sheets, at prices that span a factor of ten, and a great deal of confident misinformation about which one is &amp;ldquo;better.&amp;rdquo; The honest answer is that none of them is better, because they are not competing for the same job. Solid wood, plywood, oriented strand board, and medium-density fiberboard are four distinct engineering responses to two stubborn facts about wood: it is enormously strong and stiff for its weight but only &lt;em&gt;along the grain&lt;/em&gt;, and it swells and shrinks with the moisture in the air for as long as it exists. Every engineered panel is a strategy for defeating one or both of those facts, and each strategy costs you something else in return.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Right to Repair Honestly: The 2026 State of Play</title>
      <link>/posts/right-to-repair-honestly/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/right-to-repair-honestly/</guid>
      <description>&lt;p&gt;The framing that dominates right-to-repair coverage — greedy manufacturers versus scrappy independent shops — gets the mechanism almost entirely wrong. Manufacturers do not block repair with lawyers and warranty fine print, or at least not primarily. They block it with engineering: a battery that refuses to charge unless a cloud server confirms its serial number matches the logic board, a tractor that throws a limp-mode fault until a dealer laptop authorizes the new sensor, a car that routes its diagnostic data over a cellular link to the manufacturer&amp;rsquo;s servers instead of the standardized port under the dash. By the time a legislature debates a repair bill, the decision that actually matters — designing the part to be cryptographically married to the device — was made years earlier in a hardware spec. This is what makes right to repair a genuinely technical subject and not just a policy one, and it is why 2026 is a real inflection point: twenty-three US states have now passed repair laws, the EU&amp;rsquo;s Repair Directive reaches its transposition deadline in July, John Deere paid out a $99 million settlement in April while still fighting the FTC, and the laws are finally starting to target the &lt;em&gt;mechanisms&lt;/em&gt; rather than just gesturing at &amp;ldquo;access.&amp;rdquo; Here is the honest version of where all of it stands.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SBOMs and the Compliance Wave: From Acronym to Legal Obligation</title>
      <link>/posts/sboms-and-the-compliance-wave/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sboms-and-the-compliance-wave/</guid>
      <description>&lt;p&gt;A Software Bill of Materials is, at its core, a list of ingredients. That is the entire idea: a machine-readable inventory of every component that went into a piece of software, with enough identifying detail that someone else can answer &amp;ldquo;does this product contain the thing that just got a CVE?&amp;rdquo; without your help. The concept is so unglamorous that it spent a decade as a slide in supply-chain talks that nobody acted on. Then the EU passed a regulation with teeth, US federal procurement started demanding attestations, and the FDA made SBOMs a precondition for selling a medical device. The acronym became a deadline. What did not change is the underlying truth: an SBOM is a trivial document to produce and a hard document to produce &lt;em&gt;accurately&lt;/em&gt;, and having one tells you almost nothing about whether you are secure. This post is about the gap between those two facts — the bit-level reality of the format, the tooling that generates and consumes it, and what the regulators are actually asking for now that the compliance wave has arrived.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secrets Management in 2026: From .env Files to Short-Lived, Identity-Based Credentials</title>
      <link>/posts/secrets-management/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/secrets-management/</guid>
      <description>&lt;p&gt;Most secrets-management advice answers the wrong question. It tells you where to &lt;em&gt;store&lt;/em&gt; a long-lived API key — an env var, a vault, an encrypted file — when the real goal is to have &lt;strong&gt;fewer standing secrets and to make the ones you keep expire fast.&lt;/strong&gt; Every long-lived credential is a liability that grows with each copy: it sits in a developer&amp;rsquo;s &lt;code&gt;.env&lt;/code&gt;, in a CI variable, in a Slack message from 2024, in three container images, and in a git history nobody scrubbed. The 2026 best practice is not &amp;ldquo;guard the key better.&amp;rdquo; It is to stop minting permanent keys at all — issue short-lived credentials on demand against a proven identity, and let them expire before they can leak in any way that matters. This is the path from a &lt;code&gt;.env&lt;/code&gt; file to that model, with the practical steps at each stage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spatial Audio Honestly</title>
      <link>/posts/spatial-audio-honestly/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/spatial-audio-honestly/</guid>
      <description>&lt;p&gt;Spatial audio is the rare consumer technology that is simultaneously oversold and underexplained. The marketing promises a revolution — music that surrounds you, instruments placed in a sphere around your head, a sense of being &lt;em&gt;in&lt;/em&gt; the room with the band. The backlash dismisses it as a gimmick, a way for labels to re-sell catalog and for streaming services to justify premium tiers. Both camps are partly right and both are missing the actual engineering question, which is more interesting than either: human beings localize sound in three dimensions using only two ears, the cues that let them do it are well understood, and the honest question is not &amp;ldquo;is spatial audio real?&amp;rdquo; but &amp;ldquo;do these specific consumer formats reproduce those cues accurately enough, over the hardware people actually own, for the difference to be reliably perceptible — and when people say it sounds better, are they hearing the spatialization or something else entirely?&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Speculative Decoding Explained: Trading Compute for Bandwidth to Decode Faster</title>
      <link>/posts/speculative-decoding-explained/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/speculative-decoding-explained/</guid>
      <description>&lt;p&gt;Autoregressive decoding has a structural problem that no amount of better hardware fixes on its own: it produces exactly one token per forward pass, and each forward pass drags every weight in the model out of high-bandwidth memory whether you are computing one token or a thousand. A 70B model in FP16 is 140GB of weights; emitting a single token means reading all 140GB from HBM, doing a comparatively trivial amount of arithmetic, and throwing the loaded weights away. The math units sit mostly idle. The bottleneck is not FLOPs — it is memory bandwidth, and a single decode step uses a rounding error&amp;rsquo;s worth of the chip&amp;rsquo;s compute. Speculative decoding is the trick that spends that idle compute to buy back latency: let a cheap model guess several tokens ahead, then have the expensive model check all the guesses in one pass that costs almost the same as checking one. When the guesses are good, you get three or four tokens for the price of a single forward pass, and — this is the part that makes it usable in production rather than a research toy — the text that comes out is provably identical in distribution to what the big model would have produced on its own.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Strobe vs Continuous Light</title>
      <link>/posts/strobe-vs-continuous-light/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/strobe-vs-continuous-light/</guid>
      <description>&lt;p&gt;The strobe-versus-continuous argument is usually fought as a gear preference, but underneath it is a physics decision about &lt;em&gt;where in time your light&amp;rsquo;s energy lives&lt;/em&gt;. A studio strobe stores energy in a capacitor and dumps it through a xenon tube in roughly one to two thousandths of a second — an enormous burst of photons concentrated into an instant. A continuous LED panel does the opposite: it trickles a steady stream of light for as long as it is switched on. That one difference — energy concentrated in a flash versus energy spread over time — is not a detail; it cascades into everything that actually matters on a set. It decides whether you can freeze a splash of water, whether you can overpower the midday sun, whether what you see is what you get, how hot your subject gets, and whether you can shoot video at all. Get that physical distinction right and every &amp;ldquo;which is better&amp;rdquo; question answers itself, because the honest truth is that they are rarely competing for the same job.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Terraform vs OpenTofu vs Pulumi in 2026</title>
      <link>/posts/terraform-opentofu-pulumi-2026/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/terraform-opentofu-pulumi-2026/</guid>
      <description>&lt;p&gt;There are now three serious answers to the question &amp;ldquo;how do I declare my cloud infrastructure in code,&amp;rdquo; and they descend from two genuinely different ideas. Terraform and OpenTofu are the same idea — a declarative domain-specific language, a state file, a provider plugin model — split into two products by a license change. Pulumi is the other idea entirely: write your infrastructure in TypeScript, Python, Go, or C#, let a general-purpose language give you loops and functions and types and a package manager, and keep the same state-and-provider machinery underneath. The choice between Terraform and OpenTofu is mostly about licensing and trust. The choice between either of them and Pulumi is about what you believe a configuration language should be. This post is the honest three-way: what each tool actually is in 2026, where the lines have moved since the fork, and what is worth migrating versus what is worth leaving alone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Autonomous Driving Reality Check 2026</title>
      <link>/posts/autonomous-driving-reality-check-2026/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/autonomous-driving-reality-check-2026/</guid>
      <description>&lt;p&gt;&amp;ldquo;Self-driving&amp;rdquo; is two completely different engineering problems wearing the same marketing word, and almost every public argument about autonomy is really an argument between people talking about different ones. On one side is a service that will pick you up in a car with no driver, no steering wheel input from you, and no one liable for the trip but the company that built it. On the other is a feature you buy on a car you own, that steers and brakes impressively well on the highway, and that legally requires your hands near the wheel and your eyes on the road because &lt;em&gt;you&lt;/em&gt; are still the driver and &lt;em&gt;you&lt;/em&gt; are still responsible if it hits something. These are not two points on a smooth continuum. They are different problems with different sensor stacks, different business models, and different failure consequences. 2026 is the year the gap between them became measurable in deployed vehicles and published crash data, and the honest reading of that data is more interesting than either the boosters or the skeptics will tell you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The History of the Web</title>
      <link>/posts/the-history-of-the-web/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-history-of-the-web/</guid>
      <description>&lt;p&gt;The Web was not the Internet, and it was not inevitable. By 1989 the Internet had existed for years as a network of networks, and hypertext had been a research idea since Vannevar Bush&amp;rsquo;s 1945 &amp;ldquo;memex&amp;rdquo; and Ted Nelson&amp;rsquo;s Xanadu. What did not exist was a system that let an ordinary person, on any kind of computer, click a link and pull a document off any other computer in the world without knowing or caring where it lived. Tim Berners-Lee&amp;rsquo;s contribution was not a new idea in the abstract — it was a specific, deliberately minimal &lt;em&gt;implementation&lt;/em&gt; of three small pieces, designed to be so simple that anyone could adopt them and so permissive that nobody had to ask permission. That minimalism is why the Web won, and the next thirty-five years are largely the story of a tiny, document-oriented system being stretched, forked, and fought over until it became the application platform on which the modern world runs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The OWASP Top 10 (2025 Edition): What Changed and How to Fix Each Risk</title>
      <link>/posts/owasp-top-10/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/owasp-top-10/</guid>
      <description>&lt;p&gt;The OWASP Top 10 is the closest thing web security has to a shared vocabulary, and in 2025 it changed in ways worth paying attention to: two entirely new categories appeared, Security Misconfiguration jumped from #5 to #2, and Server-Side Request Forgery — its own entry in 2021 — got folded back into Broken Access Control. If your mental model or your scanner config still maps to the 2021 list, you are now describing risks with the wrong names and missing two categories outright. The list is not gospel; it is a data-driven snapshot of what is actually getting exploited in real applications. Here is the 2025 list, what moved and why, and the concrete fix for each item.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Physical Camera vs The Phone in 2026</title>
      <link>/posts/the-physical-camera-vs-the-phone/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-physical-camera-vs-the-phone/</guid>
      <description>&lt;p&gt;The phone won the photography war, and pretending otherwise is the fastest way to lose credibility. The overwhelming majority of photographs taken on Earth in 2026 are taken on phones, and for the overwhelming majority of those pictures the phone is not a compromise — it is genuinely the better tool, because it is in your pocket, it processes a scene more intelligently than most people could by hand, and it shares the result in seconds. Any honest comparison has to start by conceding that ground completely. The interesting question is not &amp;ldquo;which is better&amp;rdquo; in the abstract; it is the narrow, real, and stubborn set of jobs where a dedicated camera still wins decisively, and &lt;em&gt;why&lt;/em&gt; it wins, because the why is the part that marketing on both sides gets wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Pilot Training Pipeline</title>
      <link>/posts/the-pilot-training-pipeline/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-pilot-training-pipeline/</guid>
      <description>&lt;p&gt;The single most misunderstood thing about becoming an airline pilot is that the hard part is not learning to fly. A reasonably coordinated person can be landing a small airplane solo in a few weeks and can hold a private pilot certificate in a few months. The hard part is everything after: accumulating the fifteen hundred hours of flight time the federal government requires before you may sit in the right seat of an airliner, paying the roughly hundred thousand dollars it takes to get there, and surviving the years of low-paid instructing and regional flying that stand between the certificate and the career. The pilot pipeline is not an education in the usual sense. It is a long, expensive, regulation-shaped obstacle course where the binding constraint is &lt;em&gt;time in the air&lt;/em&gt;, and almost every strange feature of the system — the proliferation of certificates, the existence of flight instructing as a career stage almost nobody wants, the boom-and-bust pay — is a consequence of that one fact.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Linux</title>
      <link>/posts/the-story-of-linux/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-linux/</guid>
      <description>&lt;p&gt;On 25 August 1991 a 21-year-old computer science student at the University of Helsinki posted a message to the Usenet group &lt;code&gt;comp.os.minix&lt;/code&gt; that began: &amp;ldquo;Hello everybody out there using minix — I&amp;rsquo;m doing a (free) operating system (just a hobby, won&amp;rsquo;t be big and professional like gnu) for 386(486) AT clones.&amp;rdquo; Every clause of that sentence has aged into irony. The hobby is now the single most widely deployed body of software in human history. It is not &amp;ldquo;big and professional like gnu&amp;rdquo; because GNU&amp;rsquo;s own kernel never shipped and Linux ate the role GNU had reserved for it. It runs on far more than 386 AT clones: it runs every hyperscale data center, the top 500 supercomputers without exception, the majority of web servers, billions of Android phones, your router, your television, your car&amp;rsquo;s infotainment, and the Mars helicopter. Linux is the clearest case study in software history of how &lt;em&gt;availability beats superiority&lt;/em&gt; — how a technically unremarkable monolithic kernel, released under exactly the right license at exactly the right legal moment, with a development model that turned the entire internet into its R&amp;amp;D department, became the substrate the modern world computes on. It did not win the desktop it was supposedly fighting for. It won everything else instead, and most of its users have no idea they are running it. This is how a student&amp;rsquo;s hobby became the world&amp;rsquo;s infrastructure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Python</title>
      <link>/posts/the-story-of-python/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-python/</guid>
      <description>&lt;p&gt;Python should not have won. By the conventional metrics of language design it is slow, it is dynamically typed in an era that rediscovered the value of static checking, and at the center of its reference implementation sits a single mutex — the Global Interpreter Lock — that prevents the very multicore parallelism the hardware industry spent two decades building toward. It went through a version transition so disruptive that it split the community for a decade and is remembered as a cautionary tale taught in software-engineering courses. Its packaging story was, for most of its life, a confusing thicket of &lt;code&gt;distutils&lt;/code&gt;, &lt;code&gt;easy_install&lt;/code&gt;, &lt;code&gt;setuptools&lt;/code&gt;, &lt;code&gt;eggs&lt;/code&gt;, and &lt;code&gt;pip&lt;/code&gt; that drove newcomers to despair. And yet Python is, by most rankings in 2026, the most popular programming language in the world, the lingua franca of data science and artificial intelligence, the first language taught in a majority of universities, and the glue that holds together a staggering fraction of the software people actually ship.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tripods, Heads, and Why You Pay</title>
      <link>/posts/tripods-heads-and-why-you-pay/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tripods-heads-and-why-you-pay/</guid>
      <description>&lt;p&gt;A tripod has exactly one job — to not move — and &amp;ldquo;not move&amp;rdquo; turns out to be a far harder mechanical specification than it sounds, because the threats are not only gravity but vibration, torsion, and wind. The money you spend on a serious tripod does not buy features; it buys &lt;em&gt;stiffness&lt;/em&gt; and &lt;em&gt;damping&lt;/em&gt;: the resistance to deflecting under load, and the speed with which any vibration that does occur dies away. Almost every confused tripod-buying decision comes from thinking the spec that matters is &amp;ldquo;how much weight it holds,&amp;rdquo; when the spec that actually matters is &amp;ldquo;how little it deflects and how fast it settles.&amp;rdquo; Reframe a tripod as a stiffness-and-damping machine and the whole market suddenly makes sense: why carbon fiber costs triple aluminum, why the load rating on the box is close to meaningless, why a cheap head ruins an expensive set of legs, and why you can almost never have both rock-solid stability and genuine portability in the same purchase.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Version Control Mastery: Git, GitHub, AI Agents, and the Home Lab Stack</title>
      <link>/posts/version-control-mastery/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/version-control-mastery/</guid>
      <description>&lt;p&gt;Version control is the one non-negotiable piece of infrastructure in every software project, regardless of size. A solo developer with one machine and no deadline still benefits from version control. A team of fifty engineers shipping to production multiple times per day cannot function without it. Yet despite how long Git has been the dominant tool — twenty-plus years — most developers use perhaps thirty percent of its capability, ignore most of what makes it powerful, and have almost certainly lost work they didn&amp;rsquo;t need to lose.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What Mastering Engineers Actually Do</title>
      <link>/posts/what-mastering-engineers-actually-do/</link>
      <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/what-mastering-engineers-actually-do/</guid>
      <description>&lt;p&gt;Ask someone outside the music business what mastering is and you will usually hear some version of &amp;ldquo;making the song louder&amp;rdquo; or &amp;ldquo;the final polish.&amp;rdquo; Both are wrong in the way that matters. Mastering is the last stage of music production, the step between a finished mix and a released record, and its actual job is &lt;em&gt;translation and quality control&lt;/em&gt;: take a stereo mix that sounds good in the studio it was made in, and make it sound good everywhere — on earbuds, in a car, on a phone speaker, on a club system — while meeting the technical specifications of every format it will ship to. For roughly two decades that quiet, careful craft was hijacked by a single destructive obsession with loudness, and the most interesting thing about modern mastering is that the technology of streaming has largely ended that war and handed the craft back to its real purpose. Understanding what mastering engineers do means understanding both the work itself and the loudness war that warped it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>10 GbE at Home: When It Actually Matters</title>
      <link>/posts/10gbe-at-home-when-it-matters/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/10gbe-at-home-when-it-matters/</guid>
      <description>&lt;p&gt;The honest answer to &amp;ldquo;should I run 10 GbE at home&amp;rdquo; is almost always &amp;ldquo;not everywhere, and probably not where you think.&amp;rdquo; Gigabit Ethernet has been the default for two decades because for the things most people actually do over a network — stream video, browse, game, back up a laptop overnight — it is wildly sufficient, and the bottleneck sits somewhere else entirely. But &amp;ldquo;gigabit is enough for most things&amp;rdquo; is not the same as &amp;ldquo;faster never helps,&amp;rdquo; and the interesting engineering is in telling those cases apart: which single link, carrying which workload, is genuinely throttled by 125 megabytes per second, and whether the fix is a $1,500 fiber backbone or a $200 pair of 2.5G switches that you will never notice the cost of again. This post is about making that call with arithmetic instead of vibes — what the wire can carry, why the disk gives out first, what the cable and the heat and the power actually cost, and where on a real home network the money buys you something. It builds on the wired-backbone principles in &lt;a href=&#34;/posts/home-network-design/&#34;&gt;home network design&lt;/a&gt;; this one is specifically about the bandwidth tier.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Modern CDN, Honestly</title>
      <link>/posts/a-modern-cdn-honestly/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/a-modern-cdn-honestly/</guid>
      <description>&lt;p&gt;A content delivery network is, stripped of marketing, a fleet of reverse-proxy caches positioned close to users, fronted by routing tricks that make &amp;ldquo;close&amp;rdquo; happen automatically, and governed by a set of cache-key rules that quietly determine whether you are running a fast website or an expensive distributed &lt;code&gt;502&lt;/code&gt; generator. Everything else — the image resizer, the edge compute runtime, the DDoS scrubbing, the WAF — is a feature bolted onto that core. The hard parts are not glamorous. The hit rate that makes or breaks your origin bill is decided by how you handle &lt;code&gt;Vary&lt;/code&gt; headers, query strings, and cookies, not by which logo is on the dashboard. The latency a user feels is decided by anycast announcements and PoP density, not by the word &amp;ldquo;edge&amp;rdquo; in a press release. This post is about the actual mechanics in 2026: how a request finds the nearest point of presence, how a thundering herd of cache misses gets collapsed into one origin fetch, how images get reshaped on the wire, how the cache key is engineered, how purge really propagates, and where Cloudflare, Fastly, CloudFront, and Bunny genuinely diverge rather than where their pricing pages claim they do.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ARM vs x86 in 2026</title>
      <link>/posts/arm-vs-x86-in-2026/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/arm-vs-x86-in-2026/</guid>
      <description>&lt;p&gt;The most repeated claim in the ARM-versus-x86 debate is also the most misleading: that ARM is inherently more power-efficient because it is a &amp;ldquo;simpler&amp;rdquo; instruction set. That story was largely settled fiction by the time Apple shipped the M1, and in 2026 it is actively wrong. The decode-complexity penalty that x86 pays for its baroque instruction encoding is real but small — a few percent of die area and power on a modern chip with billions of transistors. What actually decided the last decade was not the instruction set. It was who designed the microarchitecture, what power target they aimed at, how tightly they integrated the platform, and — most importantly — the business arrangement that let them do all three at once. Apple did not beat Intel because ARM is elegant. Apple beat Intel because Apple controls the chip, the OS, the compiler, and the product, and pointed all of that at performance-per-watt while Intel was selling the same socket to a hundred laptop vendors. The ISA is a sideshow. The verdict that matters is about vertical integration, manufacturing nodes, and market segmentation, and that verdict is now legible enough to state plainly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Audio Codecs Compared</title>
      <link>/posts/audio-codecs-compared/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/audio-codecs-compared/</guid>
      <description>&lt;p&gt;The honest summary of two decades of audio compression is uncomfortable for the people who spend the most money on it: for music, a competent lossy codec at a modest bitrate is indistinguishable from the original source in a properly controlled blind test, and almost everyone who claims otherwise fails that test the moment they cannot see the file&amp;rsquo;s label. This is not an opinion. It is the consistent result of ABX listening trials run by the people who actually build and tune these encoders, and it has held across MP3, AAC, and Opus as each one got better. The interesting questions in audio codecs are therefore not &amp;ldquo;which one sounds best&amp;rdquo; — at sane bitrates the answer for most listeners on most material is &amp;ldquo;you cannot tell&amp;rdquo; — but rather which one is free of patents, which one survives at low bitrate where the differences finally become audible, which one your streaming service actually ships, and why an entire wing of the industry spent the late 2010s selling a &amp;ldquo;lossless-ish&amp;rdquo; format called MQA that turned out to be neither lossless nor necessary. This post walks the real engineering — psychoacoustic masking, the encode pipeline, the lossless math — and then uses ABX evidence to separate the differences that exist from the ones that are sold to you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bayesian Statistics for Engineers</title>
      <link>/posts/bayesian-statistics-for-engineers/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bayesian-statistics-for-engineers/</guid>
      <description>&lt;p&gt;The single most useful thing an engineer can learn about statistics is that &amp;ldquo;Bayesian&amp;rdquo; and &amp;ldquo;frequentist&amp;rdquo; are not rival religions arguing about the same question — they are precise answers to &lt;em&gt;different&lt;/em&gt; questions, and most of the heat in the debate comes from people confusing which question they actually need answered. A frequentist computes the probability of observing your data given a hypothesis: P(data | hypothesis). A Bayesian computes the probability of a hypothesis given your data: P(hypothesis | data). Those are not the same number, they are not even the same &lt;em&gt;kind&lt;/em&gt; of number, and the famous failures of statistical reasoning in engineering — misread p-values, peeking at A/B tests until they go significant, confidence intervals interpreted as if they were credible intervals — almost all come from quietly substituting one for the other. The argument of this post is narrow and practical: learn the Bayesian machinery not because frequentism is wrong (it is not, and treating &amp;ldquo;frequentist&amp;rdquo; as an insult marks you as someone who has not done the reading), but because Bayesian methods directly produce the quantity engineers usually want — a probability distribution over the thing they are trying to decide — and because in a handful of common engineering situations they are simply the better tool.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bluetooth Audio Explained</title>
      <link>/posts/bluetooth-audio-explained/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bluetooth-audio-explained/</guid>
      <description>&lt;p&gt;The single most useful thing to understand about Bluetooth audio is that the version number printed on the box — &amp;ldquo;Bluetooth 5.3,&amp;rdquo; &amp;ldquo;Bluetooth 5.4&amp;rdquo; — tells you almost nothing about how your music will sound. That number describes the radio and link layer: the modulation, the connection management, the power envelope. It does not describe which audio codec your phone and your headphones agreed to use, and the codec is where essentially all of the perceived quality difference lives. Two pairs of &amp;ldquo;Bluetooth 5.3&amp;rdquo; earbuds can sound wildly different not because of the radio but because one negotiated AAC at 256 kbps and the other quietly fell back to SBC at a bitpool that throws away the top octave of the spectrum. The version number is a marketing anchor; the codec negotiation is the engineering.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Calculus for the Person Who Forgot</title>
      <link>/posts/calculus-for-the-person-who-forgot/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/calculus-for-the-person-who-forgot/</guid>
      <description>&lt;p&gt;You took two semesters of calculus, passed the exams, and then forgot nearly all of it, and that turns out to be fine, because the version of calculus that matters for engineering work is much smaller and far more intuitive than the version you were graded on. The proof-heavy curriculum was optimized for a math department&amp;rsquo;s sense of rigor. The engineering core is optimized for answering one question over and over: if I nudge this input, how much does the output move, and in which direction should I push to make it better? That single question, asked in one variable, is the derivative. Asked in many variables, it is the gradient. Composed through a stack of functions, it is the chain rule, which is to say it is backpropagation. Run in reverse, accumulating instead of differencing, it is the integral. Everything else, the epsilon-delta limit theater, the trig-substitution gymnastics, the zoo of series convergence tests, you can let go of without guilt. This post rebuilds the useful part from the ground up, with real numbers, and tells you honestly where the missing rigor will eventually bite.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Database Indexes Explained</title>
      <link>/posts/database-indexes-explained/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/database-indexes-explained/</guid>
      <description>&lt;p&gt;An index is not free storage that makes things faster. It is a second, redundant copy of part of your data, kept permanently in sync with the table, and that synchronization is paid for on every &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, and &lt;code&gt;DELETE&lt;/code&gt; that touches an indexed column. The whole game of indexing is a trade: you spend write throughput, disk space, and maintenance overhead to buy read latency. If you do not understand both sides of that trade, you will end up with a table that has fourteen indexes, half of which the planner never uses, all of which slow down every write, and a &lt;code&gt;VACUUM&lt;/code&gt; that can never quite keep up.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DDoS Mitigation in 2026</title>
      <link>/posts/ddos-mitigation-in-2026/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ddos-mitigation-in-2026/</guid>
      <description>&lt;p&gt;The uncomfortable truth about distributed denial-of-service defense is that it is fundamentally an arms race of aggregate capacity, and you almost certainly lose it on your own. When a botnet aims 2 Tbps at your single 10 Gbps uplink, no clever firewall rule, no kernel tuning, no autoscaling group saves you — the packets saturate the pipe upstream of anything you control, and your origin goes dark not because it crashed but because the link to it is full of garbage. Modern DDoS mitigation works by inverting that capacity asymmetry: instead of one fat link to one datacenter, the defender presents hundreds of distributed edge locations, each announcing the same IP space via anycast, so that a globally-sourced attack is geographically diluted the instant it leaves the botnet. The largest scrubbing networks now field tens of Tbps of edge capacity precisely because the attacks have crossed into Tbps territory. This post is about the actual mechanisms — the attack taxonomy that determines which defense applies, the BGP plumbing that diverts traffic into scrubbing centers, the GRE tunnels that carry clean packets back, the L7 logic that separates a human from a headless Chrome instance, and the honest costs nobody puts on the marketing page.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Designing a UniFi Home Network: Cameras, Doorbells, and Multi-Zone Audio</title>
      <link>/posts/designing-a-unifi-home-network-cameras-and-audio/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/designing-a-unifi-home-network-cameras-and-audio/</guid>
      <description>&lt;p&gt;The single best decision you can make during a remodel is to treat the network as a utility you run home-run copper to, exactly like you run romex to outlets, and to do it now while the walls are open. Everything else in this post follows from that one idea. UniFi is an excellent choice for the backbone — one app for routing, switching, Wi-Fi, cameras, and doorbells, no per-camera subscription, footage that stays on a drive in your house. As of 2026 it reaches into audio too: the UniFi PowerAmp, Ubiquiti&amp;rsquo;s first amplifier, lets you keep whole-home audio inside the same ecosystem, so the one component you still buy from someone else is the speakers themselves. Capable third-party amplifiers remain a valid choice where you need a streaming service UniFi does not support, but the architecture is the same either way: a UniFi network and surveillance core, with an amplifier per zone driving speakers wired out to each room and patio. This guide walks the whole build for a roughly 3,500 sq ft house with two doorbells and four outdoor cameras: the exact gear, the wiring, the camera placement, the storage math, and the honest trade-offs. The companion pieces on &lt;a href=&#34;/posts/home-network-design/&#34;&gt;home network design&lt;/a&gt; and &lt;a href=&#34;/posts/network-segmentation-vlans/&#34;&gt;VLAN segmentation&lt;/a&gt; cover the fundamentals; this one is the concrete shopping-and-pulling plan.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Diet and Cognition: What the Evidence Actually Supports, and What the Marketing Sells</title>
      <link>/posts/diet-and-cognition/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/diet-and-cognition/</guid>
      <description>&lt;p&gt;If you want to know whether what you eat changes how your brain works, you immediately collide with the single hardest measurement problem in all of applied science: you cannot run a clean controlled experiment on human diets over the decades that cognition actually changes. You can ask people what they ate, which they misremember, and watch what happens to their minds, which is confounded by everything else about a person who eats well. So nearly the entire edifice of &amp;ldquo;this food makes you smarter&amp;rdquo; is built on observational epidemiology that is structurally biased toward optimism, and on the rare occasions someone runs a large randomized trial to check, the headline effect usually shrinks toward zero. This is not a counsel of despair. There is a defensible, evidence-weighted position on diet and cognition. But it is unglamorous, it is mostly about your blood vessels rather than any magic brain nutrient, and it bears almost no resemblance to the supplement aisle. The honest take is worth more than the hopeful one, because the hopeful one keeps getting falsified, and a skeptical engineer should want to know which of these claims would survive being tested properly — because for several of the most famous ones, we now know the answer, and it is no.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Distributed Training Parallelism</title>
      <link>/posts/distributed-training-parallelism/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/distributed-training-parallelism/</guid>
      <description>&lt;p&gt;Every distributed training strategy is an answer to one of two questions: &lt;em&gt;the model doesn&amp;rsquo;t fit&lt;/em&gt;, or &lt;em&gt;the model fits but training is too slow&lt;/em&gt;. Those are different problems with different solutions, and the most common mistake in scaling a training job is reaching for the wrong axis — sharding a model that fits fine when you just needed more data throughput, or throwing more data-parallel replicas at a model that was never going to fit on one GPU in the first place. There are exactly five axes you can split along — data, tensor, pipeline, expert, and sequence — and at thousands of GPUs you are using four or five of them at once, composed in a specific nested order that is dictated entirely by which communication operations are cheap on which network links. This post is the map: what each axis splits, what it costs in communication, and why the order you nest them in is not a matter of taste.&lt;/p&gt;</description>
    </item>
    <item>
      <title>eBPF for Networking</title>
      <link>/posts/ebpf-for-networking/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ebpf-for-networking/</guid>
      <description>&lt;p&gt;For thirty years the Linux network stack was a fixed pipeline: a packet arrived at the NIC, the driver built an &lt;code&gt;sk_buff&lt;/code&gt;, and the packet marched through netfilter hooks, routing, and the socket layer in an order you could configure with iptables rules but could not fundamentally change. eBPF broke that. It let you attach verified, JIT-compiled programs at specific points in the packet&amp;rsquo;s journey and have them make a &lt;em&gt;verdict&lt;/em&gt; — pass, drop, redirect, rewrite — at native speed, before the kernel has spent the cycles to do its normal work. The headline result is that you can drop a DDoS flood at 20+ million packets per second on a single commodity box, load-balance Layer 4 traffic without a kernel module, and replace a tangle of iptables rules with a hash-map lookup. The catch, which most eBPF marketing skips, is that &lt;em&gt;where&lt;/em&gt; you attach the program decides almost everything about what it can do and what it costs, and the two main attach points — XDP and tc — are not interchangeable. This post is about that datapath: where the hooks sit, what each can see, and what you actually pay to run code there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Embedding Models and Vector Search, Honestly</title>
      <link>/posts/embedding-models-and-vector-search-honestly/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/embedding-models-and-vector-search-honestly/</guid>
      <description>&lt;p&gt;The single most expensive mistake in production retrieval is treating embedding choice as the lever that determines quality. It is not. An embedding model is a lossy compression function that projects text into a fixed-dimensional space where geometric proximity &lt;em&gt;approximates&lt;/em&gt; semantic relatedness, and once you put a cross-encoder reranker behind it, the gap between a mediocre embedding and a state-of-the-art one collapses to single-digit points of nDCG. Where quality actually lives is in the division of labor: a fast, recall-oriented first stage (dense, sparse, or both) that pulls a few hundred candidates out of millions, followed by a slow, precision-oriented second stage that reorders the top fifty. Everything else — HNSW versus IVF-PQ, cosine versus dot product, 768 dimensions versus 1536 — is a set of trade-offs about latency, memory, and recall, not about whether your system understands meaning. This post is about getting those trade-offs right, with real numbers and real failure modes, and about being honest regarding where each component earns its keep.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Eye Strain at the Computer</title>
      <link>/posts/eye-strain-at-the-computer/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/eye-strain-at-the-computer/</guid>
      <description>&lt;p&gt;The thing you call eye strain is almost never your eyes being damaged. It is two muscle systems holding a contraction for hours, plus a tear film that has stopped renewing itself because you forgot to blink. That distinction matters, because it tells you what to fix. You cannot strengthen your way out of accommodative fatigue and you cannot supplement your way out of a dry cornea — but you can change the geometry of where you look, the humidity of the air around your face, and the cadence at which you let the focusing muscle relax. The interventions that work are unglamorous and the ones that sell well (blue-light glasses, &amp;ldquo;eye vitamins,&amp;rdquo; anti-fatigue coatings) mostly do not. This post is about telling those two groups apart with the actual evidence rather than the marketing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Game Theory in System Design</title>
      <link>/posts/game-theory-in-system-design/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/game-theory-in-system-design/</guid>
      <description>&lt;p&gt;Most systems you design assume the components obey you. A function returns what it computes; a queue holds what you push; a disk stores what you write. Game theory becomes necessary the moment a part of your system is a &lt;em&gt;party&lt;/em&gt; — a person, a company, a validator, a bidding bot — that will do whatever benefits it most regardless of what you intended. At that boundary, correctness is no longer about logic alone. It is about incentives. If the cheapest path for a self-interested actor is to lie, stall, collude, or attack, then a perfectly correct protocol will still produce the wrong outcome, because the actors are optimizing against your rules rather than following them. The central claim of this post is that game theory gives engineers a precise vocabulary for this situation, that two results in particular — the Nash equilibrium and the second-price auction — show up constantly in real infrastructure, and that the same theory honestly tells you where its own predictions stop working.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Dehumidifier Actually Works</title>
      <link>/posts/how-a-dehumidifier-actually-works/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-dehumidifier-actually-works/</guid>
      <description>&lt;p&gt;A dehumidifier is the most misunderstood appliance in the basement, starting with the phrase people use to describe it: &amp;ldquo;the refrigeration cycle in reverse.&amp;rdquo; It is nothing of the sort. Running the refrigeration cycle in reverse gives you a heat pump in heating mode — the same machine, valves flipped, pumping heat &lt;em&gt;into&lt;/em&gt; a space. A dehumidifier runs the cycle in the completely ordinary &lt;em&gt;forward&lt;/em&gt; direction, exactly like your refrigerator or air conditioner, and it removes water as a side effect of making a surface cold. What makes it a dehumidifier rather than an air conditioner is purely a packaging decision: both the cold coil and the hot coil live in the same box, in the same airstream, one behind the other, so the air that just got chilled and wrung out immediately gets reheated by the condenser before it leaves. The net effect on the room is &amp;ldquo;drier, and very slightly warmer,&amp;rdquo; which is precisely what you want and precisely the opposite of what &amp;ldquo;reverse&amp;rdquo; would suggest. Understanding that one packaging trick explains everything else about the machine: why it warms the room, why it struggles in a cold basement, why the capacity number on the box is nearly fiction, and why desiccant models exist at all.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Modern Window Is Engineered</title>
      <link>/posts/how-a-modern-window-is-engineered/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-modern-window-is-engineered/</guid>
      <description>&lt;p&gt;A window is the worst-insulated part of almost every wall it sits in, and the entire history of window engineering is a fight to make that gap less catastrophic without giving up the one thing a window is for, which is letting you see through it. A good insulated wall might resist heat flow with an R-value of 13 to 20; a single pane of glass manages about R-1, and even a good modern double-glazed unit only reaches R-3 to R-4. So the window is always the thermal hole in the building envelope, and the surprising part is how much engineering goes into shrinking that hole. A modern &lt;strong&gt;insulated glazing unit&lt;/strong&gt; — the IGU, the sealed glass sandwich that drops into a frame — is not a sheet of glass. It is a layered thermal device: two or three panes held a precise distance apart by a spacer, the cavity filled with a heavy inert gas, the whole perimeter sealed twice over against moisture and gas loss, and at least one glass surface coated with a stack of metal-oxide and silver layers a few atoms thick that is invisible to your eye but a near-mirror to thermal infrared. The cleverness is concentrated in things you cannot see: a coating you can barely measure, a gas you cannot smell, and a metric system on a little sticker that, read honestly, tells you most of what you need to know.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Rocket Engines Actually Work</title>
      <link>/posts/how-rocket-engines-actually-work/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-rocket-engines-actually-work/</guid>
      <description>&lt;p&gt;A rocket engine does exactly one thing, and it does it without any help from the outside world: it throws mass backwards as fast as possible. Everything else - the combustion chambers, the turbopumps spinning at tens of thousands of RPM, the regeneratively cooled nozzle walls glowing just short of melting, the labyrinthine plumbing that has driven engineering teams to the edge of insanity - exists to serve that single goal. Thrust is reaction. You accelerate exhaust one way, the vehicle accelerates the other way, and unlike a &lt;a href=&#34;/posts/how-a-jet-engine-actually-works/&#34;&gt;jet engine&lt;/a&gt; that breathes air, a rocket carries both its fuel and its oxidizer because it has to work in vacuum where there is no air to breathe. That self-sufficiency is the whole reason rockets can leave the planet, and it is also the source of nearly every hard problem in the field. Carrying your own oxidizer means your tanks are enormous, your mass fraction is hostile, and every fraction of a percent of efficiency you can wring out of the exhaust velocity translates into payload that actually reaches orbit instead of falling back into the ocean. This post is about how that efficiency is generated, why it is so hard to generate, and the deeply unglamorous plumbing decisions that separate a rocket that flies from a rocket that detonates on the test stand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Spray Foam Insulation Works</title>
      <link>/posts/how-spray-foam-insulation-works/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-spray-foam-insulation-works/</guid>
      <description>&lt;p&gt;Spray polyurethane foam is the only common insulation that is not a product you buy and install so much as a chemical reaction you run, in place, inside your wall — and almost everything that makes it good and everything that makes it dangerous follows from that single fact. Fiberglass batts and mineral wool arrive as finished material; you cut them and stuff them and the worst you can do is leave a gap. Spray foam arrives as two separate liquids in two separate drums, and the installer is effectively running a small, fast, exothermic polymerization on your jobsite, mixing them at a heated gun where they collide, react, and rise into a rigid or spongy plastic in seconds. When that reaction is run correctly — right temperature, right pressure, right one-to-one ratio — you get the best air seal and, in the closed-cell case, the highest R-value-per-inch of any insulation you can put in a stud bay. When it is run wrong — off-ratio, cold substrate, sprayed too thick in one pass — you get a permanent, irreversible, sometimes literally smelly mistake bonded to the bones of your house. Foam is genuinely excellent and genuinely unforgiving, and the honest version of &amp;ldquo;how it works&amp;rdquo; is mostly the story of why those two things are the same property seen from different sides.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Supply Chain Attacks Actually Work: The Anatomy of XZ, SolarWinds, and the npm Sagas</title>
      <link>/posts/how-supply-chain-attacks-actually-work/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-supply-chain-attacks-actually-work/</guid>
      <description>&lt;p&gt;Most security failures are about someone getting in who should have been kept out. Supply chain attacks are the opposite: the attacker is invited, because the code they poisoned arrives wearing the credentials of something you already trust. The &lt;code&gt;xz&lt;/code&gt; library on your system was installed by your distribution&amp;rsquo;s package manager from a signed release. SolarWinds Orion was delivered through the vendor&amp;rsquo;s own auto-update channel, signed with the vendor&amp;rsquo;s own certificate. The malicious npm package ran because you typed &lt;code&gt;npm install&lt;/code&gt; and a &lt;code&gt;postinstall&lt;/code&gt; hook did exactly what hooks are designed to do. In each case every signature checked out, every checksum matched, and every trust boundary held — because the attacker had already moved upstream of the boundary. Understanding these attacks means understanding the trust relationships that make modern software economically possible, and then watching, in forensic detail, how three of the most consequential incidents of the decade subverted them. Only then do the defenses make sense, because the wrong defenses are worse than none: they buy confidence without buying safety.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Humanoid Robots in 2026 Honestly</title>
      <link>/posts/humanoid-robots-in-2026-honestly/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/humanoid-robots-in-2026-honestly/</guid>
      <description>&lt;p&gt;The honest summary of humanoid robots in 2026 is this: the videos are real but the autonomy mostly is not, the hardware has genuinely crossed a threshold while the software has not, and the economics that justify a general-purpose bipedal robot over a purpose-built arm or wheeled platform still do not close outside of a handful of structured pilots. There is real engineering progress here, and it would be a mistake to dismiss the whole field as a stock pump. Dynamic bipedal walking is no longer a research stunt; electric actuators have caught up to the torque density that hydraulics used to monopolize; and the bet on vision-language-action (VLA) foundation models is a legitimate, well-motivated research direction rather than pure hype. But there is an enormous gap between a thirty-second clip of a robot folding a shirt and a machine that folds ten thousand shirts unattended at a cost that beats a human. This post is about where that gap actually sits, platform by platform and subsystem by subsystem, and why the marketing timelines are off by years even when the demos are not faked. If you want the contrasting story of robots that already work and ship in volume, read &lt;a href=&#34;/posts/industrial-robotics-in-2026/&#34;&gt;Industrial Robotics in 2026&lt;/a&gt;; this post is specifically about the general-purpose humanoid and the foundation-model approach that everyone is now betting the category on.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kalman Filters Explained</title>
      <link>/posts/kalman-filters-explained/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kalman-filters-explained/</guid>
      <description>&lt;p&gt;Every drone holding position in a gust, every phone that knows where you are when the GPS drops out under a bridge, every self-driving car tracking the vehicle ahead, and every rocket that knew its own attitude in 1969 is running some descendant of the same algorithm: the Kalman filter. The problem it solves is universal and unglamorous. You have a model that predicts where something will be in the next instant, and that model is wrong in small random ways. You have a sensor that measures where it actually is, and that sensor is also wrong in small random ways. Neither source alone is trustworthy enough. The Kalman filter is the provably optimal way to combine the two, weighting each by how much you trust it, and crucially it does this recursively — it keeps a single running estimate and folds in each new measurement as it arrives, never needing to store history. That recursive, constant-memory structure is why it ran on the Apollo Guidance Computer with a few kilowords of memory and why it runs today in the inner loop of an IMU sampling at a kilohertz. This post walks the core idea, the predict-and-update equations as they are actually implemented, the intuition for the Kalman gain as a trust dial between model and sensor, the linear-Gaussian assumptions that make it optimal, the EKF and UKF extensions that drag it into the nonlinear world where every real robot lives, and the honest reality that tuning the noise matrices Q and R is the part nobody warns you about.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Memory Safety in 2026: The CVE Data, the Regulatory Cliff, and the Long Goodbye to C</title>
      <link>/posts/memory-safety-in-2026/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/memory-safety-in-2026/</guid>
      <description>&lt;p&gt;For about as long as anyone has measured it, roughly seventy percent of the serious security vulnerabilities in large C and C++ codebases have been memory-safety bugs. Microsoft has reported that number across more than a decade of its own CVEs. The Chromium project reports the same proportion for its high-severity issues. The figure barely moves, which is the entire problem: it has survived every generation of better tooling, better discipline, better static analysis, and better intentions. For twenty years the industry treated this as a craftsmanship failure — programmers should simply write more careful C — and for twenty years the seventy percent did not budge. What changed by 2026 is not the languages, which have existed for years, but the framing. Memory safety stopped being a matter of professional pride and became a matter of regulatory liability and hard empirical evidence. Governments now name memory-unsafe languages as a defect class in formal policy, and for the first time there is field data proving that the only thing that reliably drives the seventy percent down is to stop writing the unsafe code, not to write it more carefully. This is the story of that transition: the proof, the adoption, the law, and the genuinely difficult path of getting off a hundred billion lines of C.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mixture of Experts, Honestly: Why Every Frontier Model Went Sparse and What It Actually Costs</title>
      <link>/posts/mixture-of-experts-honestly/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mixture-of-experts-honestly/</guid>
      <description>&lt;p&gt;By mid-2026 the architecture conversation in frontier-model land is essentially over: every model anyone cares about is a Mixture of Experts. DeepSeek-V3 and R1 are 671B-parameter MoEs that activate 37B per token. Llama 4 Maverick is 400B with 17B active across 128 experts. Llama 4 Scout is 109B with 17B active across 16. Qwen3-235B-A22B routes 22B of 235B per forward pass. The rumored GPT-4 leak that started everyone down this road was a 1.76T-parameter, 16-expert MoE with two experts active per token. Dense models past about 70B have stopped shipping at the frontier.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modern Logging Architecture: Loki, Splunk, Elasticsearch, ClickHouse, and the Cost-Per-GB That Decides Everything</title>
      <link>/posts/modern-logging-architecture/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-logging-architecture/</guid>
      <description>&lt;p&gt;At homelab scale, every logging backend works and the choice is aesthetic. At production scale, the choice is financial, and the feature comparison everyone starts with turns out to be the wrong document entirely. The number that actually governs a logging platform is cost-per-gigabyte at your ingest volume and retention, and that number is not a pricing-page line item — it is a consequence of an architectural bet each backend made about how to store and index a log line. Splunk and Elasticsearch bet on indexing everything, which makes any search instant and makes storage and ingest expensive. Loki bet on indexing almost nothing, which makes storage cheap and full-text search a brute-force scan. ClickHouse bet on columns, which makes aggregation and compression extraordinary and makes you design a schema. None of these is wrong; they are optimized for different query patterns and different budgets, and choosing the one that mismatches your workload is how teams end up either with a six-figure logging bill or a system that cannot answer the question they bought it to answer. And underneath all of it sits a lever more powerful than any backend choice: the cheapest, fastest log to store and search is the one you never ingested.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Phishing-Resistant MFA: Why Everything Short of FIDO2 Is Living on Borrowed Time</title>
      <link>/posts/phishing-resistant-mfa/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/phishing-resistant-mfa/</guid>
      <description>&lt;p&gt;Multi-factor authentication was supposed to make phishing obsolete. For a stretch of the 2010s it nearly did, because the attackers of that era were running bulk credential-stuffing campaigns against reused passwords, and a second factor — any second factor — broke that economy cold. Then the attackers adapted, and they adapted faster than the controls. A modern phishing kit does not ask you for a password and stop; it sits in the middle of your real login in real time, relays your one-time code to the actual site within its thirty-second window, and walks away with your authenticated session cookie. Another kind of attacker simply spams your phone with approval prompts until, tired and confused, you tap &amp;ldquo;yes.&amp;rdquo; A third buys your phone number from a bribed carrier rep and reads your SMS codes directly. By 2022 these were not theoretical; they were the documented root cause of breaches at Twilio, Uber, and dozens of other well-resourced companies in a single campaign season. The uncomfortable conclusion that fell out of that year is that most of what we call MFA is a speed bump, not a wall. The only factor that reliably survived contact with a competent attacker was the one cryptographically bound to the website&amp;rsquo;s identity — FIDO2 and WebAuthn — and the case for treating everything else as a stopgap is now overwhelming.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RAG Beyond Toy Demos: Chunking, Reranking, and the Evaluation Problem Nobody Solved</title>
      <link>/posts/rag-beyond-toy-demos/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rag-beyond-toy-demos/</guid>
      <description>&lt;p&gt;A retrieval-augmented generation demo is one of the most dishonest artifacts in software. You load a dozen PDFs, embed them, wire an off-the-shelf vector store to a chat model, and within an afternoon it answers questions fluently and looks like magic. Then you point it at ten thousand documents from a real organization and it confidently cites the wrong policy, misses the one paragraph that mattered, and invents a number that appears nowhere in the corpus — and you discover that the easy part was the only part you built. The hard parts of production RAG are not the embedding model or the vector database; those are commodities, and the &lt;a href=&#34;/posts/embedding-models-and-vector-search-honestly/&#34;&gt;retrieval internals are well understood&lt;/a&gt;. The hard parts are chunking the corpus so the right span is even retrievable, transforming the user&amp;rsquo;s question into something searchable, ranking aggressively enough that the answer lands in the model&amp;rsquo;s context window, grounding the generation so it cites rather than confabulates, and — the part nobody has cleanly solved — measuring whether any of it actually works. This post is about those parts: the engineering between the toy and the system, and why the demo lied to you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Random Number Generation for Engineers</title>
      <link>/posts/random-number-generation-for-engineers/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/random-number-generation-for-engineers/</guid>
      <description>&lt;p&gt;Random number generation is one of the very few places in engineering where a single misplaced function call — one that compiles cleanly, passes every test, and runs correctly for years — can silently and totally destroy the security of an entire system. A web server that calls the wrong randomness function will still serve pages. A key generator that seeds itself badly will still emit keys of the correct length and format. Nothing crashes, nothing logs an error, and nobody notices until an attacker who understood the failure has already enumerated everyone&amp;rsquo;s private keys. This is the central, uncomfortable fact about randomness: correctness is invisible from the outside, and the failure modes are catastrophic rather than graceful. The discipline that prevents disaster comes down to keeping three categories rigorously separate — true hardware randomness (TRNG), deterministic pseudo-randomness from an algorithm (PRNG), and the cryptographically secure subset of the latter (CSPRNG) — and knowing, without thinking, which one each task demands. Get the category right and the rest is mostly calling the operating system. Get it wrong and no amount of careful code review elsewhere will save you. This post walks the three categories, explains how the Linux kernel actually produces randomness in 2026, settles the long-dead &lt;code&gt;/dev/random&lt;/code&gt; versus &lt;code&gt;/dev/urandom&lt;/code&gt; debate honestly, surveys hardware entropy sources and the trust questions around them, dissects the seeding disasters that have leaked real private keys into the wild, and ends with a flat, prescriptive list of exactly what to call and what to never use.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sodium-Ion Batteries</title>
      <link>/posts/sodium-ion-batteries/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sodium-ion-batteries/</guid>
      <description>&lt;p&gt;Sodium-ion batteries are the chemistry everyone reaches for when lithium gets expensive and ignores the rest of the time. That is the whole story of the technology&amp;rsquo;s commercial life so far. When lithium carbonate spiked to roughly $80,000 per tonne at the end of 2022, sodium-ion went from a lab curiosity to a CATL product launch and a dozen Chinese pilot plants inside eighteen months. When lithium then collapsed back below $15,000 per tonne through 2024 and into 2025, every sodium-ion business plan that assumed a permanent lithium premium quietly got rewritten, and at least one high-profile Western program (Northvolt&amp;rsquo;s) was overtaken by the company&amp;rsquo;s broader collapse before it shipped anything at scale. The chemistry did not change. The arithmetic did.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spintronics and the Memory After NAND</title>
      <link>/posts/spintronics-and-the-memory-after-nand/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/spintronics-and-the-memory-after-nand/</guid>
      <description>&lt;p&gt;Every memory technology you use today stores a bit as electric charge: DRAM holds it on a capacitor that leaks in milliseconds, and NAND traps it on a floating gate that wears out a little with every write. Spintronic and ferroelectric memories abandon charge entirely. They store a bit in the orientation of a magnetic moment or the polarization of a crystal lattice — physical states that are non-volatile by nature, do not leak, and in principle never wear out. That is a genuinely different physics, and it produces a genuinely different set of trade-offs: blistering endurance and DRAM-class speed, paid for with terrible density and cost per bit. The result is not a NAND replacement, despite two decades of headlines insisting otherwise. It is something more interesting and more modest — a set of memories that win specific jobs in the hierarchy where charge-based memory is bad, while NAND keeps owning bulk storage because nothing touches it on cost. This post is about the physics of how spin-based memory works, what it can and cannot promise, and where it actually landed by 2026. The companion piece on &lt;a href=&#34;/posts/what-comes-after-nand/&#34;&gt;what comes after NAND&lt;/a&gt; handles the market-and-economics autopsy; this one is the device physics underneath it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tailscale Funnel vs Cloudflare Tunnels: Two Ways to Expose a Service Through NAT</title>
      <link>/posts/tailscale-funnel-vs-cloudflare-tunnels/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tailscale-funnel-vs-cloudflare-tunnels/</guid>
      <description>&lt;p&gt;Tailscale Funnel and Cloudflare Tunnels look interchangeable from a distance. Both let a service sitting behind a residential router — or worse, behind carrier-grade NAT where you do not even own a routable address — answer requests from the open internet. Neither one forwards a port. Neither one needs a static IP or a dynamic-DNS client babysitting your changing address. In both cases a small agent on your box dials &lt;em&gt;out&lt;/em&gt; to a provider&amp;rsquo;s network, and the provider hands inbound traffic back down that already-open connection. That shared shape is where the similarity ends. Cloudflare Tunnels is a reverse proxy bolted onto a global CDN that terminates your TLS at the edge and can gate every request behind an identity provider. Tailscale Funnel is a public on-ramp welded to the side of a private WireGuard mesh, and it deliberately does &lt;em&gt;not&lt;/em&gt; decrypt your traffic or know who is knocking. Picking between them is not a matter of taste. It is a decision about who holds your plaintext, what your threat model tolerates, and how much throughput you actually need.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Engineering of a Modern Bicycle</title>
      <link>/posts/the-engineering-of-a-modern-bicycle/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-engineering-of-a-modern-bicycle/</guid>
      <description>&lt;p&gt;A bicycle is the most efficient machine humans have ever built for converting muscle into distance — roughly 95% of the energy you put into the pedals reaches the road as forward motion, which no car, horse, or pair of running shoes comes close to matching. That efficiency is also what makes the bicycle a peculiarly honest object to engineer. There is no engine to hide behind, no software to paper over a bad chassis. Every gram, every watt of rolling resistance, every degree of frame flex shows up directly in how the thing rides and how fast it goes. Which is exactly why the cycling industry has spent four decades building an elaborate marketing language on top of differences that are sometimes real and physical, and sometimes a rounding error dressed up as a revolution.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Honest Science of Hydration</title>
      <link>/posts/the-honest-science-of-hydration/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-honest-science-of-hydration/</guid>
      <description>&lt;p&gt;The body regulates its water content more tightly and more automatically than almost any consumer-health topic admits, which is why most hydration advice is solving a problem you do not have. Your blood osmolality — the concentration of dissolved solutes in your plasma — is held within roughly a 1-2% band around 285-295 milliosmoles per kilogram, by a control loop involving osmoreceptors in your hypothalamus, antidiuretic hormone, and kidneys that can vary your urine concentration over a tenfold range. This system is fast, precise, and does not require you to count glasses. The single most useful fact about hydration is that a healthy person with access to water and a functioning thirst mechanism is already well-hydrated, and the elaborate quotas, color charts, and &amp;ldquo;you&amp;rsquo;re chronically dehydrated and don&amp;rsquo;t know it&amp;rdquo; warnings are mostly selling something. The genuinely useful knowledge is narrow: where the folklore numbers came from, what actually moves the needle (heat, exercise, illness, age), and the small number of situations where electrolytes matter rather than just flavor the water.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Quantum Computing Reality Check</title>
      <link>/posts/the-quantum-computing-reality-check/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-quantum-computing-reality-check/</guid>
      <description>&lt;p&gt;Quantum computing in 2026 is simultaneously more real and less useful than the headlines suggest, and holding both of those facts at once is the only way to think about it clearly. It is more real because the field crossed a genuine scientific threshold: error correction now demonstrably works, in the precise sense that adding more physical qubits to an encoded logical qubit makes that logical qubit &lt;em&gt;better&lt;/em&gt; rather than worse. That was not guaranteed by physics, and until recently it had never been shown. It is less useful than advertised because the machines that exist today still cannot run a single commercially valuable algorithm faster than a laptop, cannot break any cryptography you actually use, and are separated from doing so by a gap of three to four orders of magnitude in qubit count and quality. The honest story of 2026 is not &amp;ldquo;quantum computers have arrived&amp;rdquo; and not &amp;ldquo;it is all hype&amp;rdquo; — it is a hard, real, slow engineering climb from a working proof of principle toward a useful machine, with a timeline measured in years to decades depending on what you ask it to do. This is the reality check, organized around the one number that actually matters.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Reusable Rocket Economics</title>
      <link>/posts/the-reusable-rocket-economics/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-reusable-rocket-economics/</guid>
      <description>&lt;p&gt;Reusable rockets did change launch economics, but almost nothing about how the change is described in public is honest. The headline numbers are a mix of list prices that include fat margins, marginal costs that exclude the fixed costs of running a launch company, and per-kilogram figures for vehicles that have either never flown a paying payload or have flown only a handful of test articles. The defensible claim, as of 2026, is narrow and real: SpaceX drove the demonstrated, paid price of a kilogram to low Earth orbit down by roughly a factor of three to five versus the expendable rockets it displaced, and it did so primarily by recovering and re-flying the most expensive single piece of hardware on the vehicle, the first-stage booster, dozens of times. Everything beyond that - the order-of-magnitude-cheaper claims, the ten-dollars-per-kilogram Starship slides, the framing of reuse as a solved problem rather than a cadence-dependent bet - is marketing that has outrun the demonstrated data. This post separates the two. It walks through where the money actually goes on a rocket, why the booster is the thing worth saving, why reuse only pays if you fly often, what Falcon 9 actually costs SpaceX versus what it charges, and what Starship needs to demonstrate before its economics stop being a spreadsheet. The underlying machinery - why exhaust velocity and mass fraction are so punishing - is covered in &lt;a href=&#34;/posts/how-rocket-engines-actually-work/&#34;&gt;how rocket engines actually work&lt;/a&gt;; here the subject is dollars, not Newtons.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of C</title>
      <link>/posts/the-story-of-c/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-c/</guid>
      <description>&lt;p&gt;Almost every program you have ever run touched C on its way to the processor. The kernel scheduling your threads is C. The interpreter running your Python is a C program named CPython, and when that Python calls into NumPy the heavy math happens in C and Fortran. The JVM executing your Java is C and C++. Your browser&amp;rsquo;s JavaScript engine, the SSL library encrypting your traffic, the SQLite database inside your phone, the firmware in your keyboard, the libc that every other library leans on — C, C, C, C, C. A language designed in the early 1970s by one man to write one operating system on one machine became the closest thing computing has to a universal assembly language, the layer at which incompatible worlds agree to meet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Git</title>
      <link>/posts/the-story-of-git/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-git/</guid>
      <description>&lt;p&gt;Almost every line of software written today is tracked by a tool that one man wrote in roughly two weeks, in a fit of pique, because the company behind the version-control system he had been using for the Linux kernel pulled the rug out from under the project. That tool is &lt;strong&gt;Git&lt;/strong&gt;, and its origin is one of the great accidents of computing history: not a carefully planned product, not a grant-funded research project, but a load-bearing piece of infrastructure improvised under deadline pressure by a developer who openly disliked source control and had spent years refusing to adopt any of it. The thing that now underpins GitHub, GitLab, the entire open-source economy, and the daily workflow of tens of millions of programmers came into existence because a free software license got revoked in April 2005 and Linus Torvalds decided he would rather build his own than be beholden to anyone again.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Unix</title>
      <link>/posts/the-story-of-unix/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-unix/</guid>
      <description>&lt;p&gt;Almost every computer that matters in 2026 is running a descendant of an operating system that two men wrote on a cast-off minicomputer because their employer had told them to stop. The server racks of every cloud provider run Linux. The phone in your pocket runs Linux (Android) or a Mach-and-BSD hybrid (iOS). The laptop on which much of this industry is built runs macOS, which is NeXTSTEP wearing a Mac costume, which is BSD and Mach underneath. The networking gear, the embedded controllers, the supercomputers — overwhelmingly Unix or Unix-shaped. This near-total victory is one of the strangest outcomes in the history of technology, because Unix was never a product anyone set out to build, was for two decades legally barred from being sold as a real business, fragmented into a dozen incompatible commercial variants that nearly killed it, and ultimately lost the commercial war to a free reimplementation written by a Finnish student who had never seen the original source. The thing that conquered computing was not a company&amp;rsquo;s strategy. It was an idea — a small set of ideas about how software should be shaped — that turned out to be more durable than any of the corporations that fought over them. This is the story of how that happened: messy, litigious, accidental, and in the end inevitable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Training Cluster Networking: NVLink, Rails, and the Bandwidth Budget That Bounds Model Scale</title>
      <link>/posts/training-cluster-networking/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/training-cluster-networking/</guid>
      <description>&lt;p&gt;The uncomfortable truth of large-scale training is that you do not buy FLOPs, you buy a network that happens to have GPUs bolted to it. A modern accelerator can sustain on the order of a petaflop of dense math, but a training step is a sequence of matrix multiplies punctuated by collective communication — gradients summed, activations exchanged, experts routed — and the moment those collectives cannot hide behind compute, every GPU in the job sits idle waiting for the slowest link. At eight GPUs this is a tuning detail. At eight thousand it is the entire engineering problem. This post is about the fabric that decides whether your cluster scales: the two distinct networks every training system actually runs, why tensor parallelism must live inside an NVLink domain while data parallelism can cross a slower fabric, how rail-optimized topology and in-network reduction buy back bandwidth, and the arithmetic that tells you, before you sign the purchase order, whether the network will keep your GPUs fed. It is the architectural companion to the mechanics in &lt;a href=&#34;/posts/rdma-and-infiniband-from-the-ground-up/&#34;&gt;RDMA and InfiniBand from the ground up&lt;/a&gt; and the collective-software internals in the &lt;a href=&#34;/posts/nccl-deep-dive/&#34;&gt;NCCL deep dive&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Walking as Infrastructure for Thinking</title>
      <link>/posts/walking-as-infrastructure-for-thinking/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/walking-as-infrastructure-for-thinking/</guid>
      <description>&lt;p&gt;If you write code, design systems, or write prose for a living, your most expensive bottleneck is not compute or keyboard throughput — it is the rate at which your brain produces and connects ideas. That process has a known failure mode: you sit, you stare, you grind harder, and the grinding actively prevents the solution from arriving. The claim of this post is narrow and defensible: walking is not merely good for your heart, it is a cheap, repeatable intervention that changes the &lt;em&gt;cognitive state&lt;/em&gt; your brain is in, and the evidence — read skeptically, with the weak parts flagged — supports treating it as infrastructure for thinking rather than as a wellness nicety. &amp;ldquo;Infrastructure&amp;rdquo; is the operative word. You do not motivate yourself to use infrastructure; you build it into the system so that it runs by default. The case rests on three separable bodies of evidence: a cognitive one (mind-wandering, incubation, and a famous-but-overhyped creativity study), a mortality-and-metabolic one (step counts and the cost of sitting), and a logistical one (how to actually do it). The first is the most interesting and the most abused by wellness marketing, so we will handle it most carefully.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why GPUs Beat CPUs at Matrix Math</title>
      <link>/posts/why-gpus-beat-cpus-at-matrix-math/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/why-gpus-beat-cpus-at-matrix-math/</guid>
      <description>&lt;p&gt;A single GPU core is not impressive. It runs at a lower clock than a desktop CPU core, it has a feeble branch predictor, it cannot reorder instructions to any meaningful degree, and on its own it would lose a footrace to a Pentium from two decades ago. The reason a modern GPU obliterates a CPU at matrix multiplication has nothing to do with any individual core being good. It is that the GPU is a throughput machine built around a single bet: that you have so much independent arithmetic to do that the right strategy is to launch tens of thousands of threads, run them in lockstep bundles, and use that enormous pool of pending work to paper over the fact that memory is slow. The CPU makes the opposite bet. It assumes your work is serial, branchy, and latency-sensitive, so it spends its transistor budget on caches, out-of-order execution, and prediction to make one stream of instructions finish as fast as physically possible. Matrix math is the canonical workload where the GPU&amp;rsquo;s bet pays off and the CPU&amp;rsquo;s does not, and understanding exactly why requires looking at how the GPU schedules, where it keeps data, and what it added in silicon specifically to make general matrix multiply (GEMM) cheaper.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Modern Cars Are So Heavy</title>
      <link>/posts/why-modern-cars-are-so-heavy/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/why-modern-cars-are-so-heavy/</guid>
      <description>&lt;p&gt;A 1990 Honda Civic weighed about 1,000 kg. A 2026 Civic weighs roughly 1,450 kg. A 1995 Ford F-150 regular cab came in around 1,800 kg; a 2026 F-150 Lightning electric crew cab weighs about 2,950 kg, and a GMC Hummer EV crosses 4,100 kg with a battery pack heavier than an entire 1990s subcompact. Across nearly every segment, the modern car is 25 to 60 percent heavier than its equivalent from a generation ago, and the trend has not reversed in any mass-market category. The reasons are individually defensible: crash structures that save lives, batteries that eliminate tailpipe emissions, sound deadening and seats and screens that customers genuinely want. The problem is that weight compounds. A heavier car needs a stronger structure, a bigger engine or battery, larger brakes, and beefier suspension, each of which adds more weight — the mass spiral. And the costs land on third parties: road surfaces that wear out faster, tires that shed more particulate, pedestrians and occupants of lighter cars who absorb more kinetic energy in a crash. This post is an honest, quantitative accounting of where the kilograms come from, why automakers keep adding them even though they know better, and what the extra mass actually costs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>WireGuard vs OpenVPN vs Tailscale</title>
      <link>/posts/wireguard-vs-openvpn-vs-tailscale/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wireguard-vs-openvpn-vs-tailscale/</guid>
      <description>&lt;p&gt;The first thing to get straight is that comparing WireGuard, OpenVPN, and Tailscale is a category error as usually framed, because they do not all sit at the same layer. WireGuard and OpenVPN are &lt;em&gt;data-plane protocols&lt;/em&gt; — they define how two endpoints encrypt and exchange packets. Tailscale is a &lt;em&gt;control plane&lt;/em&gt; that uses WireGuard as its data plane: it does not encrypt your packets with some third protocol, it orchestrates WireGuard tunnels for you, solving the key distribution, NAT traversal, and access control that raw WireGuard leaves entirely to you. So the real comparison is two-and-a-half-way: WireGuard versus OpenVPN as cryptographic protocols, and then Tailscale (or Headscale, or Netbird) as the question of whether you want a coordination service managing WireGuard on your behalf. Almost every &amp;ldquo;which VPN should I use&amp;rdquo; argument is muddled because people compare a protocol to a managed product as if they were the same kind of thing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Autofocus Systems Explained</title>
      <link>/posts/autofocus-systems-explained/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/autofocus-systems-explained/</guid>
      <description>&lt;p&gt;Autofocus is the camera feature most photographers stopped thinking about somewhere in the late 1990s. That apparent stasis hides two complete reinventions: the migration of phase detection from a dedicated sub-mirror module onto the imaging sensor itself in the early 2010s, and the bolting of convolutional neural networks onto the AF pipeline since 2018. The headline numbers on a 2026 spec sheet are extraordinary - 759 phase-detect points, 92% frame coverage, -7.5 EV sensitivity, 120 AF/AE calculations per second, simultaneous detection of humans, birds, insects, trains, planes, motorcycles - and also misleading about what actually focuses in real-world shoots. This post unpacks the engineering: how cameras infer focus state without a distance sensor, why contrast and phase detection are fundamentally different solutions, what the on-sensor PDAF revolution changed, how neural networks decide what your subject is, and where the marketing diverges from the hit rate you will see on your card.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chiplets and Advanced Packaging: When the Die Stopped Scaling</title>
      <link>/posts/chiplets-and-advanced-packaging/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/chiplets-and-advanced-packaging/</guid>
      <description>&lt;p&gt;The most important number in modern processor design is not a transistor count or a clock speed. It is roughly 858 square millimeters — the reticle limit, the largest area a lithography scanner can expose in a single shot. For decades it did not matter, because nobody wanted a die that big and Moore&amp;rsquo;s Law made smaller transistors cheaper every couple of years. Both of those facts stopped being true at almost the same moment. AI accelerators wanted dies &lt;em&gt;larger&lt;/em&gt; than the reticle, and the cost per transistor stopped falling as new nodes got exponentially more expensive to manufacture. The industry&amp;rsquo;s response was not a better transistor. It was to give up on the monolithic die entirely and start building processors the way you build a server rack: out of multiple smaller pieces, each chosen for its job, wired together by an interconnect. Those pieces are chiplets, the wiring is advanced packaging, and together they are the most consequential shift in how chips are physically built since the integrated circuit replaced discrete transistors. The interesting part is that this was driven almost entirely by economics, not physics — and economics, unlike physics, has exceptions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Exercise for Engineers: The Minimum Effective Dose</title>
      <link>/posts/exercise-for-engineers-minimum-effective-dose/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/exercise-for-engineers-minimum-effective-dose/</guid>
      <description>&lt;p&gt;You optimize systems for a living, so you already understand the shape of the problem: there is a dose-response curve, it has a steep region and a flat region, and the entire game is finding where you stop getting paid for your inputs. Exercise is no different. The fitness industry sells you the flat part of the curve — the marginal hour seven, the supplement stack, the heart-rate-variability dashboard — because the steep part is unprofitable. The steep part is nearly free. The single highest-leverage health intervention available to a sedentary knowledge worker is going from &lt;em&gt;zero&lt;/em&gt; structured exercise to &lt;em&gt;some&lt;/em&gt;, and almost everything after that is rounding error by comparison. This post is the honest version of the numbers: what the dose-response curves actually look like, where the cheap gains live, what survived peer review, and — because most engineers fail on logistics rather than knowledge — how to wedge it into a calendar-driven day and keep it running whether you live in Phoenix, Helsinki, Delhi, or Denver.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HBM4 and the Memory Wall for AI</title>
      <link>/posts/hbm4-and-the-memory-wall-for-ai/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hbm4-and-the-memory-wall-for-ai/</guid>
      <description>&lt;p&gt;The marketing for an AI accelerator leads with floating-point operations per second, and that number is almost a lie of omission. A modern GPU can perform far more arithmetic than it can feed itself data to work on, and for the workload that actually pays the industry&amp;rsquo;s bills — running large language models — the chip spends most of its time waiting on memory, not computing. The binding constraint on AI hardware is not how fast the math units run. It is how fast you can move bytes between the memory stacks and the compute die, and that number is set almost entirely by one component: High Bandwidth Memory. This is why an H200 outperforms an H100 on identical compute silicon, why NVIDIA&amp;rsquo;s accelerator lineup is increasingly differentiated by &lt;em&gt;memory&lt;/em&gt; rather than cores, and why the company that controls HBM supply has quietly become one of the most important firms in computing. HBM4, arriving in volume through 2026, doubles the memory interface and rewrites the bottom of the stack — and understanding why that matters requires understanding the wall it is built to climb.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Image Stabilization</title>
      <link>/posts/image-stabilization/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/image-stabilization/</guid>
      <description>&lt;p&gt;Image stabilization is one of those technologies that sounds like a marketing checkbox and turns out to be a small triumph of mechatronics. The pitch is simple: your hands shake, the sensor or a lens element moves to cancel that shake, and you get sharp pictures at shutter speeds that would have been impossible on film. The reality is a hard real-time control problem layered on a hard mechanical problem, glued together by a MEMS gyroscope, a digital signal processor, and a voice-coil or magnetic-levitation actuator that must accelerate a precision component thousands of times per second without ever overshooting. The &amp;ldquo;8 stops of stabilization&amp;rdquo; number printed on the box is the polished output of a CIPA-defined shake table, and any honest engineer will tell you that real hands deliver less. This post walks the physics, the two architectures (in-lens OIS and sensor-shift IBIS), why the math differs between them, why hybrid sync exceeds the sum of its parts when it works and falls apart when it doesn&amp;rsquo;t, and why the gap between claimed stops and field stops is real but not as large as the cynical view holds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optical Interconnects: Co-Packaged Optics, Silicon Photonics, and When Photons Replace Copper</title>
      <link>/posts/optical-interconnects-co-packaged-optics-silicon-photonics/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/optical-interconnects-co-packaged-optics-silicon-photonics/</guid>
      <description>&lt;p&gt;Every accelerator built between now and the end of the decade is pin-bound, not compute-bound. The H100 will sit idle waiting for tensor data over copper before its tensor cores ever max out, the next generation will be worse, and the lever everyone is pulling is to throw out the copper and run the same bits as modulated light a few millimeters from the ASIC. This is not a new idea, it is a fifteen-year-old idea, but in 2025 and 2026 it stopped being a research program and started being a roadmap that NVIDIA, Broadcom, Intel, TSMC, Coherent, and Lumentum are signing multi-billion-dollar purchase orders against. The reason is not the press-release story about AI growth. It is the much older story that every doubling of SerDes lane rate has cost roughly the same energy per bit, that PAM-4 at 200 Gb/s already requires DSPs that draw as much as the data they recover, and that the next step on copper does not exist at any price the rack budget can absorb. So the photons come inside.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Passkeys and FIDO2 Explained</title>
      <link>/posts/passkeys-and-fido2-explained/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/passkeys-and-fido2-explained/</guid>
      <description>&lt;p&gt;The password is the worst piece of infrastructure on the internet, and we have known this for thirty years. It is reused across sites because humans cannot remember sixty unique strings. It is weak because the ones we can remember are guessable. It is phished because the protocol that exchanges it does not know which site is asking. It is breached because relying parties keep storing it badly, sometimes in plaintext, occasionally in a SQL dump that ends up on a forum. Multi-factor authentication helped at the margin, but a six-digit code typed into a phishing page is still a six-digit code the attacker now possesses, and SMS-based second factors leak through SIM swaps. The honest fix was always going to require a different protocol, not a stronger password policy. Passkeys are that protocol, finally shipped to billions of devices and consumer-facing accounts, and on World Passkey Day 2026 the FIDO Alliance reported that roughly five billion passkeys are now in active use globally, with 75 percent of surveyed consumers having enabled a passkey on at least one account. This post walks the FIDO2 stack from the bottom up, explains the registration and authentication ceremonies in enough detail that the design choices make sense, looks honestly at the sync model that nearly broke the alliance, and gives a defensible answer to the question every reader will actually have, which is whether to turn passkeys on for their bank.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RAW vs JPEG</title>
      <link>/posts/raw-vs-jpeg/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/raw-vs-jpeg/</guid>
      <description>&lt;p&gt;When you press the shutter button on a digital camera, the sensor turns photons into an array of electron counts, and the camera then has to decide what to write to the storage card. RAW and JPEG are two completely different answers to that question. A RAW file is the digital equivalent of an undeveloped negative — the raw sensor data, plus enough metadata to reconstruct an image later. A JPEG is the digital equivalent of a finished print — the processed, compressed, ready-to-share output of the camera&amp;rsquo;s internal image processing pipeline. Same scene, same sensor, same instant, two files with very different structures, sizes, and capabilities. The difference matters enormously for how you can edit the file afterward, and matters almost not at all for how it looks straight out of the camera if the camera&amp;rsquo;s processing was good. The internet&amp;rsquo;s RAW-vs-JPEG argument has been running for twenty years and almost always frames the wrong question. The right question is not which format is better but which format matches your workflow, your patience for editing, the conditions you shoot in, and what you intend to do with the file. This post walks what each format actually contains at the bit level, the in-camera processing pipeline that turns sensor data into a JPEG, what RAW makes recoverable that JPEG does not, and the honest case for each format in the situations where each genuinely wins.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Mac OS: From Cooperative Multitasking to Apple Silicon</title>
      <link>/posts/the-story-of-mac-os/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-mac-os/</guid>
      <description>&lt;p&gt;The operating system running on a Mac in 2026 shares almost no code with the one that shipped in 1984, yet the line of descent is unbroken — and far stranger than the marketing ever admitted. The modern macOS is, underneath its glass-and-blur surface, a NeXT operating system from the late 1980s, wearing a Macintosh costume, running on a kernel that fuses Carnegie Mellon&amp;rsquo;s Mach microkernel with Berkeley Unix, atop a processor architecture Apple designed in-house after abandoning two previous ones. To get from there to here, Apple had to ship a beloved system that lacked memory protection for thirteen years, watch its own replacement-OS project collapse so completely it nearly killed the company, buy the firm that had fired its founder in order to bring that founder back, and survive three full processor transitions — a feat no other major OS vendor has matched even once. This is the story of how the Macintosh operating system died, was replaced by an impostor, and became better than anyone had a right to expect.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Story of Palm: The Smartphone Before the Smartphone</title>
      <link>/posts/the-story-of-palm/</link>
      <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-story-of-palm/</guid>
      <description>&lt;p&gt;Before the iPhone, before Android, before &amp;ldquo;there&amp;rsquo;s an app for that,&amp;rdquo; there was a small grey slab with a green-ish screen that millions of people carried in a shirt pocket and tapped on with a plastic stick. Palm did not invent the personal digital assistant — Apple&amp;rsquo;s Newton beat it to market and a parade of failed &amp;ldquo;pen computers&amp;rdquo; preceded both — but Palm was the first company to ship a handheld that ordinary people kept using after the novelty wore off. It got there by ruthless subtraction: doing four things well instead of forty things badly. Then, over the following fifteen years, Palm repeatedly invented the future and then handed it to someone else through a sequence of corporate reorganizations so self-destructive they read like a case study in how not to run a technology company. By the time Palm shipped webOS in 2009 — a mobile operating system whose card-based multitasking and unified notifications the entire industry would spend the next decade copying — it was already too late. This is the story of how that happened.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ADS-B and Tracking Every Plane in the Sky</title>
      <link>/posts/ads-b-and-tracking-every-plane-in-the-sky/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ads-b-and-tracking-every-plane-in-the-sky/</guid>
      <description>&lt;p&gt;Every commercial airliner above 18,000 feet over the United States, and over most of the rest of the world, broadcasts its own GPS-derived position roughly once per second on 1090 MHz. The broadcast is unencrypted, unauthenticated, has no access control whatsoever, and is receivable by anyone with a thirty-dollar USB dongle and a quarter-wave antenna. This is &lt;strong&gt;ADS-B Out&lt;/strong&gt;, the surveillance technology that has steadily replaced traditional radar across most of the developed world&amp;rsquo;s airspace, and the side effect of the design choices is that aviation went from a system where only governments could see aircraft positions to one where any teenager with a Raspberry Pi can build the same picture and a network of hobbyists collectively delivers the world&amp;rsquo;s most comprehensive real-time flight tracking. The hobbyist receiver networks now feed FlightAware, Flightradar24, ADS-B Exchange, and OpenSky Network with millions of aircraft positions per minute, the commercial flight-tracking apps every traveler uses are built on top of this volunteer surveillance infrastructure, and journalists, activists, conservationists, and stalkers have all discovered they can track specific aircraft (private jets, military planes, executive transport) with the same tools. This post walks what ADS-B actually is at the protocol level, why a $30 software-defined radio is enough to receive the world&amp;rsquo;s most important aviation broadcast, what the flight-tracking services actually do with the data, and the honest privacy and security implications of a surveillance system that broadcasts in clear.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Air Traffic Control</title>
      <link>/posts/air-traffic-control/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/air-traffic-control/</guid>
      <description>&lt;p&gt;At any given moment over the continental United States there are roughly five thousand aircraft in the air, and a comparable number over Europe, and on a busy summer afternoon the global figure crosses twenty thousand. None of them are colliding. They are not colliding because a few thousand human controllers, sitting at consoles in concrete buildings, are continuously solving a real-time geometric puzzle whose constraints are written partly in physics, partly in international treaty, and partly in the institutional memory of every previous accident. The system they operate is the largest distributed safety-critical coordination system on the planet, and it has been routing flights around each other so reliably for so long that most passengers have no concept it exists beyond a voice on the radio.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Battery Recycling and Black Mass</title>
      <link>/posts/battery-recycling-and-black-mass/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/battery-recycling-and-black-mass/</guid>
      <description>&lt;p&gt;The clean version of battery recycling, the one in press releases, is a loop: dead pack goes in one door, a new pack comes out the other. The actual version is a chemical plant that takes shredded cell powder, dissolves it in hot sulfuric acid, and pulls cobalt, nickel, and lithium out as crystalline salts that get sold by the kilogram to cathode makers. Everything in between is fluid dynamics, solvent extraction, and unglamorous wastewater. The interesting question in 2026 is not whether the chemistry works (it does, and at industrial throughput) but whether announced capacity will catch up to feedstock supply before the feedstock arrives. Right now the bottleneck is not the plants. It is that EV packs are not dying yet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Color Management Across Cameras, Screens, and Prints</title>
      <link>/posts/color-management-across-cameras-screens-and-prints/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/color-management-across-cameras-screens-and-prints/</guid>
      <description>&lt;p&gt;Color management is the part of imaging that most photographers, designers, and printers quietly resign themselves to never fully understanding. The vocabulary alone is a thicket: sRGB, AdobeRGB, P3, Rec.2020, ICC profiles, gamma, gamut, white point, chromatic adaptation, soft proofing, rendering intent, perceptual versus relative colorimetric. The documentation tends toward either marketing oversimplification (&amp;ldquo;we support wide color!&amp;rdquo;) or expert-only depth that assumes you already know what a CIE 1931 chromaticity diagram is. The operational reality, however, is much simpler than the documentation makes it sound. There are perhaps five concepts that decide whether a color workflow produces consistent results — what device makes what color, what space the image is encoded in, what calibration profile maps one to the other, what your output medium can actually display, and what happens when the input gamut exceeds the output gamut — and once those five concepts click, the rest of the system is bookkeeping. The reason your monitor and your print never match is a specific and addressable failure of one of those five points, not a mystical incompatibility between digital and physical reproduction. This post walks the color spaces and what they actually mean, the ICC profile system that makes color portability possible, the calibration chain from camera through monitor to print, why the same file looks different in different applications, and the honest workflow that consistently produces predictable color across the whole pipeline.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Computational Photography</title>
      <link>/posts/computational-photography/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/computational-photography/</guid>
      <description>&lt;p&gt;When you press the shutter button on a modern phone, you do not take a photograph in the sense the word meant for the first 175 years of the medium. The phone records a burst — typically 8 to 15 frames captured at various exposures and possibly continuing for several seconds — aligns them despite hand shake, removes whatever moved between frames, fuses them into a single image with more dynamic range than any single exposure could provide, runs neural-network segmentation to identify faces and skies and skin and food, applies different tonal curves to each detected region, and saves the result as a JPEG that looks like a 1/250-second exposure but was actually computed from a half-second of stacked sensor data. What you see in the preview as you frame the shot is already the output of this pipeline running in real time; the moment of &amp;ldquo;capture&amp;rdquo; is a punctuation mark inside a continuous computation. This is computational photography, and it is the reason a $1000 phone with a tiny 1/1.3-inch &lt;a href=&#34;/posts/how-a-camera-sensor-works/&#34;&gt;sensor&lt;/a&gt; can produce results that, in most everyday situations, embarrass dedicated cameras with much larger sensors and better lenses. It is also why phone images have a particular look — uniformly bright shadows, hyper-detailed textures, slightly artificial skin — that some photographers reject and most consumers prefer. This post walks what the phone&amp;rsquo;s pipeline actually does between shutter press and saved JPEG, the burst-alignment and HDR-fusion math that defines the format, night-mode stacking, the semantic-segmentation neural networks that drive portrait mode and skin smoothing, and the honest line between an optical photograph and a computed reconstruction of one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Drones and Beyond-Visual-Line-of-Sight Flight</title>
      <link>/posts/drones-and-beyond-visual-line-of-sight-flight/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/drones-and-beyond-visual-line-of-sight-flight/</guid>
      <description>&lt;p&gt;The single most important fact about commercial drones in the United States is not technical. It is that almost every commercial flight that happens today is governed by 14 CFR Part 107, a rule the FAA finalized in 2016 with the implicit assumption that the remote pilot would stand in a field and watch the aircraft with their eyeballs. That single VLOS (visual line of sight) constraint is what keeps drones from doing the things people most want them to do: deliver packages across a city, inspect a 200-mile transmission line in one pass, survey a pipeline corridor without leapfrogging trucks, spray a 5,000-acre farm before the wind comes up. Almost every interesting commercial use case is a BVLOS use case, and the BVLOS path under current rules is a per-operation waiver economy that the industry has been begging the FAA to replace for almost a decade. The proposed replacement, Part 108, was published as an NPRM in August 2025, drew over 3,000 comments, blew through the February 2026 final-rule deadline set by executive order, and as of mid-2026 is still in revision with a final rule expected to take effect in phases starting later this year. This post walks the regulatory stack as it actually exists today, the autonomy stack on a modern delivery drone, who is actually flying at scale in 2026, and the honest answer to the question of whether routine drone delivery is real yet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DSP for Audio</title>
      <link>/posts/dsp-for-audio/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dsp-for-audio/</guid>
      <description>&lt;p&gt;Almost every mix decision past &amp;ldquo;pick the right microphone in the right room&amp;rdquo; comes down to two processors: equalization and compression. EQ shapes the frequency balance of a signal — boost the warmth of a vocal, cut the boxiness of a snare drum, scoop the mids out of a metal guitar tone — and compression shapes the dynamics — tame a loud word in a vocal take, glue a drum bus together, bring the breath of a quiet phrase up to where it sits in the mix. Every plugin in a digital audio workstation, every channel strip on an analog console, every &amp;ldquo;AI mastering&amp;rdquo; service that promises a finished track does fundamentally the same two things in some combination, plus a small handful of supporting effects (reverb, delay, saturation, transient shaping, stereo imaging). The math underneath EQ and compression is genuinely simpler than the plugin GUIs suggest, and once you understand what is happening to the samples flowing through, the marketing claims about which plugin sounds best collapse into much more legible engineering trade-offs. This post walks the parametric EQ as a chain of biquad filters, the compressor as a level-controlled gain element with attack and release smoothing, the look-ahead trick that fundamentally distinguishes digital from analog, and the honest gap between a $50 plugin and a $5000 hardware unit running essentially the same algorithm.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Elliptic Curve Cryptography for the Curious Engineer</title>
      <link>/posts/elliptic-curve-cryptography-for-the-curious-engineer/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/elliptic-curve-cryptography-for-the-curious-engineer/</guid>
      <description>&lt;p&gt;Elliptic curve cryptography is the algorithm family that quietly replaced RSA as the default of nearly every modern security protocol. Every TLS handshake you make in a browser, every SSH connection to a server, every Signal message you send, every Bitcoin transaction, every WireGuard tunnel, every WebAuthn passkey, every Apple iMessage between iPhones — almost all of these now use elliptic curves under the hood, where a decade ago they used RSA. The motivation was simple and engineering-driven: elliptic curves deliver the same cryptographic strength as RSA with keys an order of magnitude smaller, signatures and key exchanges that are correspondingly faster, and a security margin that scales more gracefully as required strength grows. The cost was that the math is less intuitive than RSA — the operation underneath is not multiplication of large primes but point addition on an algebraic curve — and the implementation pitfalls (nonce reuse in ECDSA, side-channel attacks, malicious curve parameters) bit early implementations badly enough that the field had to evolve through several generations of curves and signature schemes before settling on the modern recommendations. This post walks what an elliptic curve actually is at the level a working engineer needs, why the discrete-log problem on a curve is hard, what makes Curve25519 different from NIST P-256 both politically and technically, how signing differs from key exchange, and the honest engineering case for each curve in 2026.&lt;/p&gt;</description>
    </item>
    <item>
      <title>EV Battery Thermal Management</title>
      <link>/posts/ev-battery-thermal-management/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ev-battery-thermal-management/</guid>
      <description>&lt;p&gt;Two EVs with identical batteries can deliver very different driving experiences, and almost all of the difference comes down to thermal management. A lithium-ion cell is genuinely happy only in a narrow temperature band — roughly 15 to 35 °C for discharge, even narrower for fast charging — and outside that band the cell delivers less power, charges more slowly, ages faster, and in extreme cases catches fire. A car is the worst possible place to put such a fussy device: it sits in a parking lot for hours absorbing summer sun, it lives at -20 °C in a Norwegian winter, it dumps hundreds of amps into the pack on a highway entrance ramp, and the driver expects all of this to be invisible. The job of the thermal management system is to make the cell believe it is sitting on a lab bench at room temperature regardless of what the car is actually doing. The vehicles that do this well — modern Teslas, the Hyundai-Kia E-GMP platform, the Lucid Air, the latest BYD Han — deliver flat range across seasons, repeatable fast charging, and battery degradation curves that look almost good. The ones that do this poorly are the early Nissan Leafs, whose air-cooled packs degraded rapidly in hot climates and gave EVs a reputation they have spent fifteen years living down. This post walks why the cells care, how modern packs hold the band, why preconditioning at a fast charger is now table stakes, the heat pump that increasingly handles both the cabin and the pack, and the honest failure modes the marketing brochures do not advertise.&lt;/p&gt;</description>
    </item>
    <item>
      <title>EV Drivetrains</title>
      <link>/posts/ev-drivetrains/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ev-drivetrains/</guid>
      <description>&lt;p&gt;An internal-combustion car carries a startling amount of machinery whose only job is to compensate for the engine&amp;rsquo;s flaws. The transmission exists because a piston engine produces useful torque only inside a narrow speed band, usually between 1,500 and 6,000 RPM, and cannot start from rest under load. The differential exists because a single crankshaft must drive two wheels that turn at different speeds in corners. The starter motor exists because the engine cannot start itself. The flywheel, dual-mass damper, torque converter, clutch packs, synchros, and shift forks all exist to paper over the same fundamental problem: combustion produces lumpy, narrow-band torque that needs translation before a wheel can use it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Grid-Scale Storage</title>
      <link>/posts/grid-scale-storage/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grid-scale-storage/</guid>
      <description>&lt;p&gt;A grid-scale battery is a building full of cell phones that got promoted. The chemistry inside a Tesla Megapack or a Sungrow PowerTitan is the same lithium iron phosphate technology that lives in cordless drills, stacked into modules, racks, and shipping containers until the aggregate energy capacity hits hundreds of megawatt-hours and the power output competes with a gas peaker. The transition from research curiosity to load-balancing the California grid every summer evening happened in roughly a decade. Cell chemistry got most of the press, but the unglamorous parts &amp;ndash; containerised thermal management, bidirectional 1500V DC inverters, hierarchical battery management firmware, and the market-design tricks that let frequency response pay for the whole asset &amp;ndash; did the real lifting. This post walks the architecture from cell to substation, the revenue streams that justify the capex, the lessons baked in by Hornsdale and the multiple Moss Landing fires, and the honest economic comparison against pumped hydro that the storage industry would rather you skip.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hardware Security Modules and Secure Enclaves</title>
      <link>/posts/hardware-security-modules-and-secure-enclaves/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hardware-security-modules-and-secure-enclaves/</guid>
      <description>&lt;p&gt;Every modern security architecture eventually arrives at a question that cryptography alone cannot answer: where do the keys live, and how do you stop an attacker who has root on the machine from stealing them? Software-protected keys — even ones encrypted at rest — are eventually loaded into memory to be used, and at that moment they are recoverable by any sufficiently privileged process. The answer the security industry settled on is a family of hardware devices whose entire job is to hold cryptographic keys, perform operations using those keys when authorized, and refuse to reveal the keys themselves under any circumstance. Hardware Security Modules in data centers, Trusted Platform Modules on motherboards, Apple&amp;rsquo;s Secure Enclave on iPhone SoCs, Google Titan chips in Pixels, YubiKeys hanging off USB ports — all of them implement variations on the same architectural pattern, with very different price points, threat models, and use cases. The hard part of using any of them is understanding what they actually protect against, what attestation lets a remote system prove about a key held inside one, and the honest physical-tamper story that decides whether a determined attacker with the device in hand can recover the key. This post walks the family, the threat model each member addresses, the attestation chain that ties hardware-protected keys to verifiable identity, the FIPS 140-3 certification regime, and the honest limits — including the side-channel attacks that have repeatedly defeated devices that claimed to be impervious.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hash Functions Explained</title>
      <link>/posts/hash-functions-explained/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hash-functions-explained/</guid>
      <description>&lt;p&gt;Cryptographic hash functions are the workhorse primitive of modern computing. Every TLS handshake derives its keys with one. Every git commit identifier is one. Every password storage scheme worth using is built on one. Every blockchain block links to its parent through one. Every code-signing scheme depends on them, every digital signature signs them rather than the underlying message, every content-addressed storage system (IPFS, Cas, Nix, deduplicating backups) names files by them. The reason hash functions are everywhere is that they offer a unique combination of guarantees that nothing else provides: take an arbitrary-length input and produce a fixed-length output where the only way to find an input mapping to a specific output is to try inputs more or less at random, and the only way to find two distinct inputs producing the same output is to try about 2^(n/2) random inputs before getting lucky. Those two properties — preimage resistance and collision resistance — are what make a hash a hash. The interesting part is that nobody has proven any specific hash function actually has those properties; we have functions that have &lt;em&gt;resisted&lt;/em&gt; attack for decades and inferring that resistance into the future, and we have a graveyard of functions (MD5, SHA-1, RIPEMD, snefru) whose resistance failed. This post walks what a cryptographic hash function actually guarantees, the Merkle-Damgard construction at the heart of MD5/SHA-1/SHA-2 and the sponge construction at the heart of SHA-3, the parallel Merkle tree underneath BLAKE3, why the length-extension attack matters in practice, and the honest 2026 decision tree for which hash to use where.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Headphone Amps and DACs</title>
      <link>/posts/headphone-amps-and-dacs/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/headphone-amps-and-dacs/</guid>
      <description>&lt;p&gt;Headphone audio is the hobby that suffers the largest gap between what is sold and what is true. The same engineer who would never buy a $1,000 HDMI cable will earnestly debate whether a $4,000 USB cable improves the soundstage of their delta-sigma DAC, and the same person who can recite Nyquist&amp;rsquo;s theorem will sometimes insist that 24-bit/192 kHz playback of a 1973 studio recording sounds noticeably better than the 16/44.1 CD. The interesting thing is that the underlying engineering is not mysterious. A DAC is a well-understood signal processing block, headphone amplification is Ohm&amp;rsquo;s law plus a sensitivity number, and the audibility of any of it can be tested with a double-blind ABX in an afternoon. The honest answer for almost everyone is that a $9 dongle drives most headphones to indistinguishable fidelity from anything else on the market, and the only real audio purchase that matters is the headphone itself. This post walks the actual measurements, the impedance and sensitivity math that decides whether you need an amp at all, and a calibrated list of which audiophile claims survive controlled listening tests and which collapse the moment a volume-matched switch is added.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Home Battery Systems, Honestly</title>
      <link>/posts/home-battery-systems-honestly/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-battery-systems-honestly/</guid>
      <description>&lt;p&gt;A home battery is sold to you as four products at once: a generator&#xA;replacement, a solar maximizer, an arbitrage machine, and a vague piece&#xA;of &amp;ldquo;energy independence.&amp;rdquo; Three of those four are real, the fourth is&#xA;mostly marketing, and the same 13.5 kWh box has to do all of them at&#xA;once. The brochure averages them and prints a payback period. We will&#xA;not.&lt;/p&gt;&#xA;&lt;p&gt;This post is about how to actually decide whether to spend $11,000 to&#xA;$25,000 on a home battery in 2026. We pull apart the three real use&#xA;cases (backup, self-consumption, TOU arbitrage), the round-trip&#xA;efficiency tax that eats every kWh you cycle, the kWh-cycle warranty&#xA;math that tells you the true marginal cost, and the four products&#xA;installers will quote you: Tesla Powerwall 3, Enphase IQ Battery 10C,&#xA;FranklinWH aPower 2, and the Sonnen/LG outliers. Then honest payback&#xA;numbers for three archetypes: a Texas customer on 1:1 net metering, a&#xA;Californian on NEM 3.0, and a New Englander who just wants the lights&#xA;to stay on when the ice storm hits.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Camera Sensor Works</title>
      <link>/posts/how-a-camera-sensor-works/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-camera-sensor-works/</guid>
      <description>&lt;p&gt;A camera sensor is a photon-counting machine glued to a clock. Light arrives, electrons accumulate, a circuit measures the accumulation, an analog-to-digital converter turns the measurement into a number, and a 2D array of those numbers becomes the image. Everything photographers argue about — full-frame versus phone, low-light performance, dynamic range, that intangible &amp;ldquo;look&amp;rdquo; of a particular body — reduces to how well that pipeline runs and how big each pixel is. The physics is brutally simple and brutally unforgiving: photons either land on your silicon or they do not, and electrons either get counted accurately or get drowned in noise. A 1.4-micron phone pixel and a 6-micron full-frame pixel are not different in kind; they differ in area, and area is destiny when your signal is a Poisson process. This post walks the modern CMOS imaging pipeline end to end — photoelectric conversion, the Bayer color filter array, front-side versus back-side illumination versus stacked architectures, column-parallel ADCs, the read-noise floor, full-well capacity, and the resulting dynamic range — then explains, with real numbers from Sony, Nikon, Canon, Fuji, and Phase One sensors, why the same scene produces wildly different files on different chips, and where computational photography genuinely closes the gap and where it cannot.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Jet Engine Actually Works</title>
      <link>/posts/how-a-jet-engine-actually-works/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-jet-engine-actually-works/</guid>
      <description>&lt;p&gt;The piece of engineering most people stare at out an airliner window without really seeing is the engine — a giant fan in front of a smaller core, hung under each wing on a strut, swallowing tons of air per second and spitting out hot exhaust to push the airplane forward. Modern airliner engines look nothing like the pure turbojets that defined the 1950s and 60s, and they work for fundamentally different reasons. The engine on a Boeing 787 or Airbus A350 is about 95% propulsive &lt;em&gt;fan&lt;/em&gt;, with a small turbine core in the middle whose only job is to spin that fan. The engineering effort that made this possible — high-bypass turbofan architecture, single-crystal turbine blades cast around hollow cooling passages, composite fan blades the size of dining tables, computerized full-authority engine controls — turns out to also be the reason modern commercial aviation is dramatically more fuel-efficient and dramatically quieter than its predecessors, and the reason airliners today are mostly twin-engine machines crossing oceans that once required four-engine 747s. This post walks the Brayton thermodynamic cycle that every jet engine implements, the compressor-combustor-turbine sequence at the engine&amp;rsquo;s core, why the bypass ratio decides everything about modern engine behavior, the materials and metallurgy that fix the temperature ceiling, and the honest maintenance and reliability reality that explains why a turbofan engine costs tens of millions of dollars per copy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Modern ICE Engine Really Works</title>
      <link>/posts/how-a-modern-ice-engine-really-works/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-modern-ice-engine-really-works/</guid>
      <description>&lt;p&gt;A modern naturally-aspirated 2.5-liter four-cylinder matches a 1995 BMW M3&#xA;inline-six on peak horsepower, returns 35 mpg combined doing it, runs on&#xA;87-octane regular, idles smoother than that M3 ever did, and converts roughly&#xA;40% of the chemical energy in its fuel into work at the crankshaft. Carbureted&#xA;engines topped out around 25 to 28% brake thermal efficiency at their best&#xA;operating point and spent most of their lives well below that. The&#xA;12-percentage-point improvement looks small on paper. It is the difference&#xA;between a 1990 Civic and a 2025 RAV4 Hybrid. The way it was extracted is a&#xA;decades-long campaign against four enemies every gasoline engine fights:&#xA;knock, pumping losses, heat loss to the coolant, and exhaust enthalpy&#xA;escaping out the tailpipe. Each buzzword on a modern engine spec sheet,&#xA;direct injection, twin-scroll turbo, dual VVT, cooled EGR, Miller cycle,&#xA;cylinder deactivation, is a counterattack against one of those four. This is&#xA;what they actually do, why downsized turbo fours displaced V6s, and where&#xA;the ceiling sits.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How ABS, Stability Control, and Traction Control Actually Work</title>
      <link>/posts/how-abs-stability-control-and-traction-control-work/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-abs-stability-control-and-traction-control-work/</guid>
      <description>&lt;p&gt;Marketing lists ABS, Traction Control, and Electronic Stability Control as three separate features with three dashboard icons. Inside the car they are one feature wearing three hats. They share the same four wheel-speed sensors, the same hydraulic modulator, the same ECU, and largely the same control loops. The only difference is which signal is the trigger: a wheel decelerating too fast (ABS), a driven wheel accelerating too fast (TCS), or the whole car rotating differently than the driver asked for (ESC). Once a trigger fires, all three reach for the same actuator: pulse an individual brake caliper at 10 to 15 Hz to push that wheel back to the slip ratio where the tire makes peak grip. This post walks the shared hardware, the slip-ratio target, the valve choreography that makes brake pulsing possible, the yaw-rate feedback loop that turns ABS hardware into a stability system, and the hard ceiling physics imposes regardless of how clever the ECU gets.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Industrial Robotics in 2026</title>
      <link>/posts/industrial-robotics-in-2026/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/industrial-robotics-in-2026/</guid>
      <description>&lt;p&gt;If you read the press releases, factories in 2026 are humming with humanoid robots, foundation-model policies, and self-programming arms that learn from a few demonstrations. If you walk an actual factory floor, you see something almost the opposite. The high-volume cells are dominated by the same caged six-axis arms that have been there for twenty years, plus a slowly growing population of force-limited collaborative robots doing screw driving, machine tending, palletizing, and a long tail of small-batch tasks that used to be uneconomical to automate. The interesting story is not that robots are taking over manufacturing; it is that the industry has settled into a stable architecture, governed by a pair of safety standards most people outside the field have never heard of, and shaped by an integrator economy where the robot itself is the cheapest part of the system. This post is a walk through what is actually deployed, what the standards actually say, and where the honest gap between marketing and reality sits in 2026.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Inverse Kinematics for the Working Engineer</title>
      <link>/posts/inverse-kinematics-for-the-working-engineer/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/inverse-kinematics-for-the-working-engineer/</guid>
      <description>&lt;p&gt;Tell a robot arm to move its gripper to a specific point in space and you have asked it to solve a problem that, on its face, looks like trivial geometry. In practice it is one of the more subtly hard problems in robotics, and it is the reason every motion-planning stack ships a small library of competing solvers with names like KDL, TRAC-IK, BioIK, and IKFast. The forward problem — given the joint angles, find where the gripper ends up — is easy: chain together the transformations, multiply the matrices, read off the position. The inverse problem — given the desired gripper pose, find the joint angles that produce it — is hard because there can be zero solutions (the target is out of reach), many solutions (the arm can fold itself in several different ways to reach the same point), or near-misses where the math becomes numerically unstable. Add a deadline (control loops want answers in single-digit milliseconds), redundancy (a 7-joint arm has infinite solutions for any reachable point), and singularities (the configurations where the math falls apart) and you have an entire research field that the working engineer mostly wants to consume rather than rediscover. This post walks the forward and inverse problems honestly, the analytic-versus-numerical split, the Jacobian and damped least squares, the singularities that bite every implementation, and the solvers in 2026 you can just import.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lens Engineering</title>
      <link>/posts/lens-engineering/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/lens-engineering/</guid>
      <description>&lt;p&gt;A modern camera lens looks superficially like a tube with glass in it, and behaves like a precision optical instrument because the inside of that tube contains 12 to 25 individual shaped pieces of carefully chosen glass — some made of specialty materials that cost more per gram than gold — assembled to micron tolerances and arranged to fight a specific set of optical defects that any single piece of glass would have produced. Every photograph the &lt;a href=&#34;/posts/how-a-camera-sensor-works/&#34;&gt;camera sensor&lt;/a&gt; ever sees is filtered through the lens first, and every defect the lens does not correct shows up as some artifact in the image: soft corners, color fringing around bright edges, geometric distortion, vignetting, off-center bokeh, ghosting from internal reflections. The engineering behind a modern lens is one of the more underappreciated stories in consumer technology, partly because it is essentially invisible (you cannot see optical correction; you can only see what fails when it is absent), and partly because the marketing has been dominated for decades by the more visible camera bodies. This post walks the aberrations every lens has to correct, what aspherical and low-dispersion glass and fluorite elements actually do, why image stabilization and autofocus add weight to modern designs, why fast glass is heavier than slow glass for hard physical reasons, and the honest case for a $2000 professional prime over a $400 kit zoom — and the cases where the kit zoom is actually fine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Li-ion Chemistry, Honestly</title>
      <link>/posts/li-ion-chemistry-honestly/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/li-ion-chemistry-honestly/</guid>
      <description>&lt;p&gt;A lithium-ion cell is not one thing. Beneath the marketing label &amp;ldquo;Li-ion&amp;rdquo; sits a family of chemistries whose differences are larger than the similarities, and the cathode is where almost all of those differences live. The anode is graphite in nearly every commercial cell shipping today. The electrolyte is some variation on LiPF6 dissolved in carbonates. The separator is a polyolefin film. But the cathode — the part of the cell that actually stores and releases lithium during charge and discharge — is the variable that decides energy density, cycle life, thermal runaway risk, fast-charge capability, cost per kilowatt-hour, and even the shape and size of the cell housing. Three cathode families now dominate the automotive and stationary storage markets: lithium iron phosphate (LFP), lithium nickel manganese cobalt oxide (NMC), and lithium nickel cobalt aluminum oxide (NCA). Each is honest about its strengths and slightly evasive about its weaknesses, and the trade-offs between them are not subtle. By mid-2026, LFP has crossed from &amp;ldquo;the cheap option for entry-level cars&amp;rdquo; to powering roughly two-thirds of new EV sales in China and a fast-rising share everywhere else, and the reasons have very little to do with what battery datasheets emphasize on page one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Live Sound Engineering</title>
      <link>/posts/live-sound-engineering/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-sound-engineering/</guid>
      <description>&lt;p&gt;A studio mix engineer works in a treated room with calibrated monitors, an undo button, and as many takes as the budget allows. A FOH engineer at a 5,000-seat amphitheater works in a room they have never heard before, on a PA they did not tune, with a band whose stage volume is already 95 dB-A at the downstage edge. The mix happens once, in real time, with no second take. The two jobs share signal-flow vocabulary, but the engineering problems are not the same. Live sound is dominated by three constraints the studio does not have: the room is uncontrollable, performers must hear themselves over their own kit, and the margin between &amp;ldquo;loud and clear&amp;rdquo; and &amp;ldquo;feeding back&amp;rdquo; is a few dB of headroom the engineer manages in their head while the show is happening. This post walks the architecture that grew up around those constraints — line arrays and point-source rigs, the gain-before-feedback budget, in-ear monitors, and the honest distance between a polished studio mix and a great FOH mix.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Microphone Engineering</title>
      <link>/posts/microphone-engineering/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/microphone-engineering/</guid>
      <description>&lt;p&gt;A microphone has one job: convert acoustic pressure waves into an electrical voltage that mirrors them. Three transducer mechanisms have survived a century of competitive engineering, and they have survived because each one is genuinely better than the others at something. A Shure SM58 will beat a Neumann U87 on a screaming vocalist in a loud room every time, not because the SM58 is better but because its moving-coil transducer cannot be overloaded by SPL that would send the U87&amp;rsquo;s FET preamp into clipping. A Royer R-121 ribbon will make a Marshall stack sound like a record while a small-diaphragm condenser on the same cabinet sounds like an ice pick. Choosing a mic is not really about price, brand, or fidelity in the abstract; it is about matching the physics of the transducer to the physics of the source and room. This post walks the three transducer families, the polar patterns that decide what each mic actually hears, the trade-offs that make a hundred-dollar workhorse outperform a thousand-dollar boutique on certain sources, and a practical framework for choosing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modern Avionics</title>
      <link>/posts/modern-avionics/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-avionics/</guid>
      <description>&lt;p&gt;If you climbed into a 1975 Boeing 727 and then into a 2026 Airbus A350, you would not recognize the two as the same trade. The 727 cockpit had three crew, around a hundred round instruments, and roughly the same scan philosophy as a P-51 Mustang. The A350 has two pilots, six large LCDs, two sidesticks, and a deep stack of software between the pilot&amp;rsquo;s hands and the control surfaces. Almost everything visible has changed. What is interesting is how little of the actual job has changed underneath. A pilot in 2026 still spends most of the flight monitoring instruments and managing energy, the way pilots have since the 1930s. The difference is that the instruments are virtual, the energy management is largely delegated to a flight management computer, and the hard part of the job has shifted from &amp;ldquo;fly the airplane&amp;rdquo; to &amp;ldquo;supervise a machine that flies the airplane, and notice quickly when it gets something wrong.&amp;rdquo; This post walks what a glass cockpit actually replaced, what the FMS does, how autopilots and autoland chains are built, why flight computers are triplicated, and the honest gap between manual and automated flight as it stands today.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PID Control from First Principles</title>
      <link>/posts/pid-control-from-first-principles/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pid-control-from-first-principles/</guid>
      <description>&lt;p&gt;PID is the feedback loop that runs an embarrassing fraction of industrial reality. Your home thermostat is PID. The cruise control on a car is PID. A chemical plant holding a reactor at temperature is a stack of nested PIDs. A 3D printer&amp;rsquo;s nozzle and bed temperatures are PIDs. The autopilot on a small aircraft is mostly PIDs in cascade. The reason this one algorithm dominates a century of control engineering is that it is the simplest controller that works on the broadest class of real systems, requires no model of the plant it controls, and can be tuned by hand on hardware you do not fully understand. Its three terms — proportional, integral, derivative — each correspond to an intuition that maps cleanly onto how a thoughtful human would manually drive a system to a setpoint, and once you internalize what each one is doing you can read the behavior of almost any real-world plant by watching how it responds to disturbances. This post walks PID from first principles: what each term is, why the math is the way it is, how to tune one without a textbook, the standard failure modes (windup, derivative kick, deadtime) that bite every practitioner, and the honest gap between the textbook controller and the one that actually keeps a real plant working.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Post-Quantum Cryptography in 2026: Kyber, Dilithium, and the Migration That Already Started</title>
      <link>/posts/post-quantum-cryptography-in-2026/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/post-quantum-cryptography-in-2026/</guid>
      <description>&lt;p&gt;The migration nobody wanted to do has quietly started without you. If you are using a recent Chrome, Firefox, or Edge to read this on a Cloudflare-fronted site, your TLS handshake is already running &lt;code&gt;X25519MLKEM768&lt;/code&gt;: a hybrid that combines a classical Curve25519 key exchange with the lattice-based ML-KEM-768 that NIST standardized as FIPS 203 in August 2024. If you SSH into a host running OpenSSH 10 or newer, your KEX has been &lt;code&gt;mlkem768x25519-sha256&lt;/code&gt; by default since April 2025. The post-quantum transition stopped being a slide in a CISO deck about 18 months ago. It is now the operational reality that lives in your &lt;code&gt;tls_handshake_duration_seconds&lt;/code&gt; p95 graph, in middlebox failure tickets, and in the size of your ClientHello messages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Regenerative Braking</title>
      <link>/posts/regenerative-braking/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/regenerative-braking/</guid>
      <description>&lt;p&gt;Every time a conventional car slows down, the kinetic energy of the moving mass is converted into heat at the brake rotors and dissipated into the surrounding air. That energy came from the fuel; it is now gone. An electric vehicle has the option to do something different: command the drive motor to act as a generator, dragging the wheels and pushing current back into the battery, recovering a fraction of the kinetic energy that would otherwise have heated the brakes. That fraction is real, and it is genuinely meaningful for vehicle range, particularly in stop-and-go driving where every traffic light is a small kinetic-energy donation back to the pack. It is also more bounded than the marketing implies, less impressive than the headline numbers suggest, and complicated to coordinate with the friction brakes that must remain available for emergencies, ABS events, and the parts of the deceleration curve where the motor cannot help. The story of regenerative braking is a story about physics that constrains the upside, control systems that decide what mix of regen and friction to apply at each moment, the driver-feel choices that shape one-pedal versus coast-and-blend driving, and the honest efficiency numbers across the kind of driving people actually do. This post walks all of those and ends with where regen really lives in the lifecycle of an EV&amp;rsquo;s energy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Room Acoustics for the Home Studio</title>
      <link>/posts/room-acoustics-for-the-home-studio/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/room-acoustics-for-the-home-studio/</guid>
      <description>&lt;p&gt;A bad room can make a $3,000 microphone sound mediocre, and a great room can make a $100 dynamic sound professional. The difference is acoustics — the way sound waves bouncing around between walls, floor, and ceiling sum and cancel before they reach the microphone (or the listener&amp;rsquo;s ears at the mix position), creating dips, peaks, ringing, and a frequency response that the most carefully chosen &lt;a href=&#34;/posts/microphone-engineering/&#34;&gt;microphone&lt;/a&gt; and signal chain cannot escape. The treatment that fixes a small room is unglamorous, larger than the internet implies, almost never the foam-tile-and-egg-crate combination sold on Amazon, and falls into three honestly different categories — absorption, diffusion, and bass trapping — each addressing a different physical problem. There is also a category that gets confused with acoustic treatment but is not: &lt;strong&gt;soundproofing&lt;/strong&gt;, the separate engineering problem of keeping sound from passing through walls between rooms, which involves mass and decoupling rather than foam panels and is a different (and dramatically more expensive) project. This post walks the small-room acoustics problem honestly, the modal frequencies that ruin every untreated bedroom-studio, what absorption and diffusion and bass trapping actually do, the difference between soundproofing and treatment, and a practical first-treatment plan for the room you have.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ROS and ROS2 Explained</title>
      <link>/posts/ros-and-ros2-explained/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ros-and-ros2-explained/</guid>
      <description>&lt;p&gt;The Robot Operating System is not an operating system. It does not have a kernel, a scheduler, or a process model of its own; it runs on top of plain Linux. What ROS actually is — and what makes it the convention nearly every modern robot speaks — is a publish-subscribe message bus, a set of conventions for naming, packaging, and discovering software modules, and a sprawling ecosystem of robot-specific libraries (sensor drivers, motion planners, perception stacks, simulators) built around that bus. Whether your robot is a research-lab manipulator arm, a Roomba, an industrial AGV, a quadruped, or a custom hobby project, the odds that someone has already written half the software you need &lt;em&gt;as a ROS package&lt;/em&gt; are uncomfortably high. The cost of that ecosystem is real — a learning curve that takes weeks, a build system that is its own discipline, and a runtime model that does interesting things at scale — and the version split between ROS1 and ROS2 has spent the better part of a decade fragmenting that ecosystem in ways that matter for what you actually build. This post walks what ROS is, what changed when ROS2 replaced the central master with DDS, how the build-and-launch story actually fits together, and an honest take on the learning curve for someone trying to use it for the first time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SLAM in Practice</title>
      <link>/posts/slam-in-practice/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/slam-in-practice/</guid>
      <description>&lt;p&gt;SLAM — Simultaneous Localization and Mapping — is the chicken-and-egg problem at the heart of mobile robotics. To build a map, you need to know where you are when you observe each landmark; to know where you are, you need a map to localize against. SLAM solves both problems at once by treating them as a single joint optimization: given a stream of noisy sensor measurements, find both the robot&amp;rsquo;s trajectory and a consistent map of the environment that together best explain the measurements. The first practical solutions appeared in the late 1990s and were good enough to demonstrate the principle on indoor robots with whisker sensors. Modern SLAM systems run on a Roomba navigating your living room, on the autonomous vehicles mapping city streets, on quadrotors flying through warehouses, and on the AR system on your phone tracking the table in front of you — and the math underneath is essentially the same family in all of them. What changes between applications is the sensor modality, the scale of the map, the speed requirements, and how much accuracy you really need. This post walks the chicken-and-egg structure, the sensor and algorithm choices that decide what a SLAM system is good at, the loop-closure problem that determines whether your map stays consistent over hours, and the honest accuracy reality across the price spectrum from a $300 vacuum to a $300,000 research vehicle.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Solid-State Batteries: What Is Real, What Is Hype</title>
      <link>/posts/solid-state-batteries/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/solid-state-batteries/</guid>
      <description>&lt;p&gt;If you have read a press release about solid-state batteries in the last fifteen years, you have read approximately the same press release. An automaker or a startup announces a breakthrough. The headlines promise a thousand kilometers of range, ten-minute charging, and no more thermal runaway. A pilot line is mentioned. A year is named, usually four to six years out. The stock moves. Then the year arrives, the pilot line is real but tiny, the cells are sampled but not sold, and the breathless year slides four to six years further out. The cycle repeats. The science is genuinely advancing, but the gap between the lab cell and the automotive pack is not a marketing problem. It is a manufacturing, interface chemistry, and stack mechanics problem that ten years of capital have not closed and will not close in the next two. This post describes what &amp;ldquo;solid-state&amp;rdquo; actually means at the electrolyte level, lays out the three material families and what is wrong with each, explains why the dendrite story is more complicated than the marketing claims, and parses what Toyota, QuantumScape, Samsung SDI, and CATL have actually demonstrated versus announced. Then we name a calibrated timeline for when you can actually buy a car with one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stepper vs Servo vs BLDC</title>
      <link>/posts/stepper-vs-servo-vs-bldc/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/stepper-vs-servo-vs-bldc/</guid>
      <description>&lt;p&gt;Pick the wrong motor class for a project and no amount of firmware will save it. A stepper that misses a step at the wrong moment ruins a print; a hobby RC servo asked to hold a robot arm in place burns its driver in twenty minutes; a BLDC without a half-decent commutation strategy cogs hard enough to feel through a steel frame. The three families look interchangeable from the outside — same NEMA bolt patterns, same shaft diameters, same generic &amp;ldquo;motor&amp;rdquo; label in a parts list — but they are three genuinely different machines with three different control philosophies, three different torque-vs-speed shapes, and three different failure modes. The decision is rarely about which motor is &amp;ldquo;best.&amp;rdquo; It is about matching the motor&amp;rsquo;s natural behavior to what the mechanism actually needs: precise open-loop positioning, closed-loop trajectory tracking, or efficient high-speed torque with minimal weight. This post walks each family at the rotor level, the math that separates a noisy six-step BLDC from a silky FOC one, why stepper torque collapses at speed, what closed-loop steppers actually solve, and the realistic project-level decisions that fall out of all of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The CAN Bus and Modern Vehicle Electronics</title>
      <link>/posts/the-can-bus-and-modern-vehicle-electronics/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-can-bus-and-modern-vehicle-electronics/</guid>
      <description>&lt;p&gt;A modern car is a fleet of computers wrapped in sheet metal. Open the hood of any 2026 vehicle and there is no longer a clean separation between mechanical and electronic parts; the engine has 30 sensors and three or four dedicated microcontrollers, the transmission has its own, every door has at least one for windows and locks, every brake corner has a small one for ABS, the radio is a Linux box, the climate control is another, the battery management on a hybrid or EV is another stack entirely, and the head unit on a premium car is something close to a tablet running a custom OS. The total ECU (electronic control unit) count in a typical 2026 vehicle ranges from 70 in a basic compact to over 150 in a luxury SUV, and the network that ties them together is the most quietly consequential piece of every car on the road. Anyone who has plugged an OBD-II scanner into the port under the dash has spoken to that network. Anyone who has wondered why a $40 bus error code can mean a $4,000 repair has felt its consequences. This post walks why &lt;strong&gt;CAN&lt;/strong&gt; (Controller Area Network) won the first round of in-vehicle networking, what &lt;strong&gt;CAN FD&lt;/strong&gt; changed, the supporting roles of &lt;strong&gt;LIN&lt;/strong&gt; and &lt;strong&gt;FlexRay&lt;/strong&gt;, the move to automotive Ethernet and the &lt;strong&gt;zonal architecture&lt;/strong&gt; that is replacing the flat-harness model, the &lt;strong&gt;gateway&lt;/strong&gt; at the center coordinating it all, and what an OBD-II scanner is actually doing when it reads your check-engine code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Signal Protocol and the Double Ratchet</title>
      <link>/posts/the-signal-protocol-and-the-double-ratchet/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-signal-protocol-and-the-double-ratchet/</guid>
      <description>&lt;p&gt;The Signal Protocol is, by any reasonable count, the most widely deployed piece of cryptographic engineering in human history. It is the algorithm beneath Signal Messenger, WhatsApp (used by over two billion people daily), Google Messages&amp;rsquo; RCS end-to-end encryption, Meta&amp;rsquo;s Messenger, and most of the smaller secure messaging apps that came after. The reason it has displaced every other end-to-end encryption design is that it solves a specific set of operational problems that other protocols solve poorly or not at all: it produces a new key for every message, it survives the compromise of any single key without exposing the rest of the conversation, it works asynchronously when one party is offline, it handles out-of-order message delivery, and it does all of this with one &lt;a href=&#34;/posts/elliptic-curve-cryptography-for-the-curious-engineer/&#34;&gt;elliptic-curve Diffie-Hellman&lt;/a&gt; and a couple of &lt;a href=&#34;/posts/hash-functions-explained/&#34;&gt;hash function&lt;/a&gt; operations per message — efficiently enough to ship on phones. The cleverness of the design is in two interlocking machines called &lt;em&gt;ratchets&lt;/em&gt; that grind the key material forward in a way that protects past messages from future compromise (forward secrecy) and recovers from compromise after a short window (post-compromise security). This post walks what end-to-end encryption actually buys you, the X3DH initial key agreement that bootstraps a Signal session, the symmetric and Diffie-Hellman ratchets that drive the per-message key derivation, how the protocol handles message ordering and missed messages, and the honest answer to &amp;ldquo;what can an attacker who compromises my phone read?&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tire Engineering</title>
      <link>/posts/tire-engineering/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tire-engineering/</guid>
      <description>&lt;p&gt;Every dynamic input your car receives from the road — acceleration, braking, cornering, ride comfort, road noise — comes through four patches of rubber roughly the size of a sheet of paper. Everything that happens above those patches is just suspension geometry shaping how the patches load and unload; everything that happens beneath them is friction physics modulated by the rubber&amp;rsquo;s chemistry, temperature, and the geometry of the tread cutting through whatever the road surface is doing. A tire is one of the more under-engineered-feeling components on a modern car — a black donut, looks like every other black donut, often the cheapest part of a major repair bill — and one of the most consequential. The same vehicle on two different tires can feel like two different cars; the same tire on the same vehicle at two different temperatures can stop in distances that differ by tens of feet. This post walks the rubber chemistry that decides the grip-versus-life trade-off, the contact-patch physics that decides what good geometry even means, the tread patterns that handle water and snow, the UTQG ratings that try to make all of this comparable, the genuine reason &amp;ldquo;all-season&amp;rdquo; tires are usually the wrong choice for any specific season, and how to actually choose tires.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vinyl Engineering</title>
      <link>/posts/vinyl-engineering/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vinyl-engineering/</guid>
      <description>&lt;p&gt;Vinyl was supposed to be dead by 1990. Then it was supposed to be dead by 2000. According to the RIAA&amp;rsquo;s 2025 year-end report, U.S. vinyl revenue passed one billion dollars for the first time since the early 1980s, growing for the nineteenth consecutive year, and it now outsells CDs by roughly three to one in unit terms. The format that lost a war to the compact disc, then lost another war to MP3s, then lost a third to streaming, is in 2026 the only physical music format that anyone outside collectors actually buys. The interesting question is not whether vinyl is winning some imaginary fidelity contest against lossless streaming (it is not), but why a format constrained by a needle dragging through a plastic groove sounds &lt;em&gt;different enough&lt;/em&gt; that people pay a premium for it. The answer is mostly engineering, partly mastering choices, and a little bit of ritual. Let&amp;rsquo;s walk through the actual signal chain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Airliners Are Twin-Engine Now</title>
      <link>/posts/why-airliners-are-twin-engine-now/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/why-airliners-are-twin-engine-now/</guid>
      <description>&lt;p&gt;Look at the gate at any major hub in 2026 and the widebodies waiting for pushback are almost all twins. A 777-300ER bound for Singapore, a 787-9 for Sao Paulo, an A350-1000 for Auckland, an A330neo for Doha. The four-engine 747s are gone from passenger service at almost every major carrier, the A340 left a decade ago, and the tri-jets - DC-10, L-1011, MD-11 - exist only in nostalgia and the occasional FedEx freighter. This is a remarkable inversion. In 1985 the FAA forbade twin-engine commercial aircraft from operating more than 60 minutes single-engine flying time from an adequate alternate airport. That single rule made trans-oceanic twins illegal and trans-oceanic three- and four-engine jets mandatory. Today twins routinely fly 330-minute and even 370-minute diversion routes over the Pacific and the Southern Ocean. The shift was enabled by two things working together: an engine-reliability improvement of roughly two orders of magnitude, and an ETOPS regulatory framework that translated that reliability into route authority. Economics did the rest, because once you can fly the route on two engines, you almost always want to. This post walks the math behind the 60-minute rule, the ETOPS framework that replaced it, the route history that twin-engine widebodies opened up, and the honest counterargument from the pilots who still think more engines is a feature, not a cost line item.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zero-Knowledge Proofs Without the Math Dump</title>
      <link>/posts/zero-knowledge-proofs-without-the-math-dump/</link>
      <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zero-knowledge-proofs-without-the-math-dump/</guid>
      <description>&lt;p&gt;Zero-knowledge proofs are one of the more genuinely strange things in modern cryptography: a way for one party (the prover) to convince another (the verifier) that a statement is true while revealing nothing beyond its truth. Not the witness that makes it true, not the values involved, not anything beyond the fact &amp;ldquo;yes, this statement holds.&amp;rdquo; Described that way it sounds like wishful thinking, but it turns out to be a real mathematical construction that has been refined over forty years of academic research and, in the last five, has finally hit production at scale — primarily in blockchain rollups that compress thousands of transactions into a single proof, in privacy systems that let you prove you are over 18 without revealing your birthday, in identity protocols that let you prove you hold a credential without disclosing the credential itself. The technology has also generated a remarkable amount of hype, much of it disconnected from what zero-knowledge proofs actually do well in 2026. This post walks what ZK actually proves and how, without dropping into the algebra; the engineering split between zk-SNARKs and zk-STARKs and what each is good at; the trusted-setup ceremony some SNARK families require and why it is a real concern; the honest applications worth knowing about versus the ones that are mostly hype; and the surprisingly large proving and verification costs that decide whether ZK is the right tool for any given problem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Blue Light and Circadian Rhythm</title>
      <link>/posts/blue-light-and-circadian-rhythm/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/blue-light-and-circadian-rhythm/</guid>
      <description>&lt;p&gt;The &amp;ldquo;blue light is destroying your sleep&amp;rdquo; story is one of the more interesting case studies in how a real biological mechanism gets flattened into wellness marketing. Every part of the headline is true at the level of textbook neuroscience — short-wavelength light around 460 nm activates a specialized population of retinal cells called intrinsically photosensitive retinal ganglion cells, which signal the suprachiasmatic nucleus to suppress pineal melatonin secretion, which is one of the inputs to the circadian timing of sleep. And every part of the headline collapses, or partly collapses, when you read the studies actually testing it on humans staring at modern phones at the brightness they actually use. The amber glasses do almost nothing for the average person. Night Shift mode does almost nothing for the average person. What does something is light &lt;em&gt;intensity&lt;/em&gt; and light &lt;em&gt;timing&lt;/em&gt;, the two variables both the marketing and most consumer interventions quietly ignore. This post walks the real biology, the real evidence on each intervention, and the calibrated take that emerges: blue light is a real lever on circadian biology, but the way to actually pull it has almost nothing to do with the color filter on your phone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Build an E-Paper Status Dashboard</title>
      <link>/posts/build-an-e-paper-status-dashboard/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/build-an-e-paper-status-dashboard/</guid>
      <description>&lt;p&gt;An e-paper status dashboard is the project that turns an ordinary homelab metric into a piece of low-key furniture: a small white panel on the wall that shows the things you actually want to know — your network bandwidth, your solar output, the weather, the laundry status, when the next train leaves — without lighting up your room or asking for attention. It is also the project that teaches you how aggressively the display technology shapes the software. E-paper is bistable, slow, and stubborn about ghosting; the limitations are not bugs to engineer around but design constraints that force a sane refresh cadence, a sparser layout, and a different programming model than a screen-on dashboard. Build one and you stop thinking about pixels-per-second and start thinking about updates-per-hour and milliwatts-per-day. This post walks the hardware decision (a Raspberry Pi versus an ESP32 with ESPHome), the refresh physics that decide what you can change and how often, the rendering pipeline from data source to panel, and the enclosure and mounting choices that decide whether your dashboard lives on the desk for a month or on the wall for years.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dishwasher and Water-Heater Engineering</title>
      <link>/posts/dishwasher-and-water-heater-engineering/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dishwasher-and-water-heater-engineering/</guid>
      <description>&lt;p&gt;The two appliances most people understand least are the two that quietly burn the most water and energy in a typical home: the dishwasher and the water heater that feeds it. Both are usually written off as dumb boxes — one sprays water on plates, the other keeps water hot — but each is a tidy piece of thermal and control engineering. A modern dishwasher is not a rinsing machine; it is a sealed reactor that recirculates a surprisingly small volume of hot chemistry across your dishes dozens of times, sensing how dirty the water is and heating it on board. And the water heater is the single appliance where the choice between three architectures — storage tank, tankless, and heat pump — swings your energy bill by hundreds of dollars a year. Understanding both means understanding a handful of numbers about heat, water, and feedback. Here they are.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DOCSIS and How Cable Internet Works</title>
      <link>/posts/docsis-and-how-cable-internet-works/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/docsis-and-how-cable-internet-works/</guid>
      <description>&lt;p&gt;Cable internet is the engineering equivalent of paving a highway over an old streetcar route: it works, it carries enormous traffic, and the reason every junction is in a strange place is that the original infrastructure was built for something else entirely. The coax in the wall behind your modem was laid down in the 1970s and 1980s to deliver television channels — analog VHF and UHF carriers, each occupying a 6 MHz slice of spectrum, broadcast in one direction from a regional headend to millions of subscribers&amp;rsquo; TV sets. Internet over that infrastructure had to fit &lt;em&gt;between&lt;/em&gt; the TV channels, share a single coax trunk with hundreds of neighbors, find some way to send data &lt;em&gt;upstream&lt;/em&gt; on a medium that was never wired for two-way traffic, and do all of it without rewiring the city. The protocol that makes this work is DOCSIS — Data Over Cable Service Interface Specification — and the explanation for almost every quirk of cable internet behavior (the upload that is a tenth of your download, the latency that spikes the moment anyone uploads anything, the modem reset that fixes everything for a week) lives in DOCSIS. This post walks the spectrum layout that defines what cable can do, the upstream bottleneck that defines what it cannot, the generational progression from DOCSIS 3.0 to 4.0, the headend equipment your modem talks to, and the honest comparison to the fiber-PON architecture that is steadily eating cable&amp;rsquo;s market share.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Microwave Oven Actually Works</title>
      <link>/posts/how-a-microwave-oven-actually-works/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-microwave-oven-actually-works/</guid>
      <description>&lt;p&gt;The microwave oven is the most quietly sophisticated appliance in the average kitchen and the one wrapped in the most confident misinformation. It contains a genuine piece of radar-era physics — a cavity magnetron, the same class of device that let WWII aircraft see at night — generating a beam of radio waves at a power that would be dangerous if it leaked, all behind a door you slam without a thought. And yet the popular explanation of how it cooks is almost entirely false. It does not heat food by &amp;ldquo;resonating&amp;rdquo; with water molecules; 2.45 GHz is nowhere near any resonance of water. It does not cook &amp;ldquo;from the inside out&amp;rdquo;; the waves barely penetrate a centimeter and the center of anything thick is heated the slow way, by conduction. The turntable is not a convenience; it exists to drag your food through a fixed pattern of hot and cold spots that would otherwise leave the meal half scalding and half frozen. And the reason a fork sparks but a dinner plate with a gold rim is a gamble comes straight out of how electric fields concentrate on sharp metal. Here is what is actually happening inside the box.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How GPS Computes Your Position</title>
      <link>/posts/how-gps-computes-your-position/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-gps-computes-your-position/</guid>
      <description>&lt;p&gt;The Global Positioning System is one of the most extraordinary pieces of engineering most people use every day without noticing. A pocket-sized device with no special hardware listens to signals weaker than thermal noise, decodes them by correlating each one against a known pseudorandom pattern, measures how long each signal took to arrive with nanosecond precision, accounts for special- and general-relativistic time dilation on satellite clocks running 38 microseconds per day faster than Earth&amp;rsquo;s, solves a four-dimensional geometry problem in real time, and tells you where you are within a few meters. It does this anywhere on the planet, with no infrastructure on the ground required, in tens of milliseconds. The fact that GPS works at all is a vindication of relativity that engineers had to actually build into the system or watch it fail within minutes. The fact that it works on a five-dollar receiver is a smaller miracle that happens to be entirely the product of clever signal processing. This post walks the physics of how a fix is computed from four satellites you cannot see, why three would not be enough, the relativistic clock corrections that would otherwise destroy the accuracy, how a phone hears the signal at all, and the difference between a cold fix that takes thirty seconds and a warm one that takes one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Noise-Cancelling Headphones Work</title>
      <link>/posts/how-noise-cancelling-headphones-work/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-noise-cancelling-headphones-work/</guid>
      <description>&lt;p&gt;Put on a good pair of noise-cancelling headphones in a roaring airplane cabin and the drone collapses into a soft pressure. It feels like magic, but it is not subtraction by silence — it is a microphone listening to the engine, a chip computing the engine&amp;rsquo;s exact opposite, and a speaker playing that opposite into your ear canal fast enough that the two waves meet and flatten. The whole system is a feedback control loop racing the speed of sound, and almost everything interesting about how these headphones behave — why they kill rumble but not voices, why cheap ones hiss, why &amp;ldquo;transparency mode&amp;rdquo; exists at all — falls directly out of the physics of that race. Active noise cancellation (ANC) is not an audio feature bolted onto a speaker. It is a real-time controller whose plant is the wave equation, and once you see it that way, the marketing words stop mattering and the engineering becomes legible.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Immutable Linux Distros: NixOS, Silverblue, and bootc</title>
      <link>/posts/immutable-linux-distros-nixos-silverblue-bootc/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/immutable-linux-distros-nixos-silverblue-bootc/</guid>
      <description>&lt;p&gt;The traditional Linux package model has not changed in any deep way since the 1990s: you run &lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;dnf&lt;/code&gt;, or &lt;code&gt;pacman&lt;/code&gt;, the package manager writes new files into a shared root filesystem, runs post-install scripts, and your running system is now subtly different from every other one of its kind, including the one you tested against. This works most of the time and fails in ways that are infuriating precisely because they are intermittent — a half-applied transaction, a config-file conflict, a library upgrade that breaks something on next boot. Immutable distros throw out the entire premise. They treat the operating system as a versioned, atomically swapped artifact instead of an accumulating pile of files, give you a previous version sitting next to the current one for instant rollback, and quarantine your personal changes into well-defined seams. The three serious implementations in 2026 — NixOS, the OSTree-based Fedora Silverblue/Kinoite/Bluefin family, and the newer bootc model that swaps OSTree&amp;rsquo;s bespoke transport for OCI container registries — answer &amp;ldquo;what does immutable mean&amp;rdquo; in three different ways, with three different costs. This post walks them honestly: what changes at the filesystem, what you give up in ergonomics, and who should actually run one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Klipper Input Shaping</title>
      <link>/posts/klipper-input-shaping/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/klipper-input-shaping/</guid>
      <description>&lt;p&gt;There is a particular kind of 3D-printing ugliness called &lt;em&gt;ringing&lt;/em&gt; — the rippled echo that appears just past every sharp corner of a print, where the moving toolhead has tried to change direction faster than the frame can absorb the inertia, and the frame vibrates a few cycles before settling. For thirty years the cure was simply to move slower: print at acceleration low enough that the frame never excited its own resonance, accept whatever speed that bought you, and live with it. Klipper&amp;rsquo;s &lt;strong&gt;input shaping&lt;/strong&gt; turned that compromise into an engineering problem with a clean answer: instead of slowing the toolhead down, send it a &lt;em&gt;shaped&lt;/em&gt; motion command whose vibrations cancel the frame&amp;rsquo;s resonance by destructive interference. The math is not new — it comes from a 1990s control-systems literature on crane operation and robotic arms — but applying it to consumer 3D printers required moving motion planning off the dollar microcontroller on the printer and onto a Raspberry Pi where the heavy computation could happen. The result is one of the most consequential firmware shifts in hobby 3D printing this decade: a $300 Ender 3 with a shaped Klipper config prints meaningfully cleaner at 200 mm/s than the same printer on Marlin did at 50 mm/s. This post walks what input shaping actually does, how an ADXL345 accelerometer campaign tells you the frequencies you need to cancel, why the extruder gets its own separate treatment via pressure advance, and the honest setup complexity Klipper adds in exchange for the speed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Liquid-Cooling a Homelab</title>
      <link>/posts/liquid-cooling-a-homelab/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/liquid-cooling-a-homelab/</guid>
      <description>&lt;p&gt;Liquid cooling looks like an upgrade and is sometimes a hazard, and the difference between those two outcomes is decided by how honestly you understand the thermal budget you are actually solving for. A modern CPU dumping 200 W of heat into a 240 mm AIO is a solved engineering problem with five-nines reliability. A 600 W RTX 5090, an AI training rig, or a pair of GPUs running inference in your office is a fundamentally different thermal problem, and the answer to that one is not always &amp;ldquo;more water.&amp;rdquo; The interesting thing about cooling at this scale is that it is mostly arithmetic — watts of heat in must equal watts of heat out, and every component (block, pump, radiator, fan) has known capacity numbers — but the homelab world is full of builds that ignore the arithmetic and instead trust that &amp;ldquo;liquid is better than air&amp;rdquo; will carry them. It will not. This post walks the actual thermodynamics, the AIO-versus-custom-loop split, what changes when heat is GPU-class instead of CPU-class, the failure modes that bite hardware running 24/7, and the honest cost-benefit against simply moving more air through a chassis you already own. The right answer is sometimes water and often is not.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LoRaWAN for Long-Range IoT</title>
      <link>/posts/lorawan-for-long-range-iot/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/lorawan-for-long-range-iot/</guid>
      <description>&lt;p&gt;Most wireless protocols start by asking how much bandwidth they can squeeze out of a slice of spectrum. LoRaWAN starts by asking the opposite question: given a battery the size of a coin, a sub-gigahertz radio, and a single gateway on a roof, how far away can a packet still be decoded? Once you frame the problem that way, the whole protocol stops looking strange. The chirp modulation, the absurdly slow data rates, the byzantine class-A receive windows, the hard duty-cycle caps that won&amp;rsquo;t let your device transmit for more than a few seconds an hour — they are all consequences of optimizing for link budget and battery life at the expense of everything else. LoRaWAN is what you get when range and ten-year battery life are the only metrics that matter, and throughput, latency, and bidirectional responsiveness are line items you are willing to spend almost down to zero. This post walks the physics of chirp spread spectrum, the spreading-factor and airtime trade-off, the star-of-stars architecture and what The Things Network actually provides, the duty-cycle rules that govern transmission in the EU and US, and the honest comparison with NB-IoT, LTE-M, Zigbee, and Wi-Fi. The takeaway is that LoRaWAN is one of the few wireless technologies that genuinely delivers what it promises — as long as you only ask it to do what it was built to do.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Matter, Thread, and Zigbee Untangled</title>
      <link>/posts/matter-thread-and-zigbee-untangled/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/matter-thread-and-zigbee-untangled/</guid>
      <description>&lt;p&gt;The smart-home industry has spent five years telling people that Matter, Thread, and Zigbee are three competing options, and the result is an entire ecosystem of confused buyers and demoralized installers. They are not competing options. They live at different layers of the network stack, and treating them as alternatives is like asking whether you should use TCP or HTTP for your website. Once you see the stack correctly, almost every confusing thing about smart-home protocols becomes legible: why a Matter device can run &amp;ldquo;over Thread&amp;rdquo; or &amp;ldquo;over Wi-Fi,&amp;rdquo; why a Zigbee bulb needs a hub but a Thread bulb sort of does not, why two Apple and Google border routers can fight each other on the same Thread network, and why &amp;ldquo;Matter compatibility&amp;rdquo; on a box does not actually mean what you assume. The point of this post is to draw the stack honestly, walk the IPv6 mesh that Thread builds underneath, explain what commissioning actually does, and tell you what the protocols deliver in 2026 versus what the marketing promises. The mismatch is real, and it shapes what you should buy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mechanical Keyboards and RSI</title>
      <link>/posts/mechanical-keyboards-and-rsi/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mechanical-keyboards-and-rsi/</guid>
      <description>&lt;p&gt;The mechanical-keyboard community has spent fifteen years producing better hardware than the typing world has ever had access to and, simultaneously, more confident folklore about ergonomics than any other corner of consumer tech. Both halves of that sentence are true. The hardware is genuinely better — programmable, split, columnar layouts with thumb clusters, low-force tactile switches, fully tunable firmware — and some of it really does reduce repetitive strain in ways the research supports. The folklore, however, conflates &lt;em&gt;feels nice&lt;/em&gt; with &lt;em&gt;prevents injury&lt;/em&gt;, sells switches as medical interventions, and rounds off the boring evidence-based interventions that actually do most of the work. If you write code for a living, type meeting notes all day, or spend hours in chat tools, you have a real interest in knowing which of those layers helps. This post separates them honestly: the actual mechanism by which keyboard work injures hands, the evidence on what helps, where the mechanical-keyboard world is correct and where it overclaims, and the hierarchy of interventions ranked by how much they actually move the needle. Posture and habits sit at the top. Hardware sits below them. Enthusiast folklore — clicky switches, particular keycap profiles, brass plates — does not appear on the list at all.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RCS Messaging</title>
      <link>/posts/rcs-messaging/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rcs-messaging/</guid>
      <description>&lt;p&gt;For thirty years SMS was the messaging protocol of last resort — the thing that worked across every carrier, every phone, every country, at the cost of being a 160-character monospaced relic with no encryption, no read receipts, no high-resolution images, no anything. RCS — Rich Communication Services — was supposed to replace it in the early 2010s and instead spent fifteen years in carrier limbo before Apple&amp;rsquo;s reversal in 2024 finally pushed it across the line. In 2026 it is the default green-bubble protocol on both Google Messages and Apple Messages, finally with end-to-end encryption in the GSMA Universal Profile 3.0 specification rolling out across carriers, and the messaging interoperability problem is closer to solved than at any point in the smartphone era. It is also still a mess once you look at the seams. This post walks what RCS actually standardizes versus what the marketing implies, how the Universal Profile and Google&amp;rsquo;s Jibe cloud underneath it actually work, the Apple saga and what changed when it ended, what end-to-end encryption now covers and what still falls outside it, and the SMS fallback behavior that quietly undermines every assumption you might have about the system. The honest framing: RCS is finally the thing it was supposed to be, and that thing is &lt;em&gt;good&lt;/em&gt;, not perfect.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Resin vs FDM 3D Printing, Honestly</title>
      <link>/posts/resin-vs-fdm-3d-printing-honestly/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/resin-vs-fdm-3d-printing-honestly/</guid>
      <description>&lt;p&gt;The resin-versus-FDM debate online is almost entirely conducted in marketing photos and resolution numbers, and almost never in the operational reality of running either machine in your house for a year. The marketing is correct that an MSLA resin printer produces surfaces FDM cannot match and miniatures with detail FDM cannot resolve. The marketing leaves out that producing those parts requires a chemical-handling workflow, a real ventilation plan, nitrile gloves, isopropyl alcohol management as a waste stream, and a tolerance for getting sticky photopolymer on something you care about roughly once a month. FDM is the technology that produces uglier parts and a tidier life; resin is the technology that produces beautiful parts and a small chemistry lab in your spare room. Choosing the wrong one for your situation is the most common 3D-printing mistake, and the cost of that mistake is not money — it is the gradual realization that the new printer is too much work to use, sitting unused on a shelf six months later. This post separates the two technologies the way they should be compared: not on what they can produce, but on what they cost you to operate. For the underlying physics — how layers fuse on an FDM nozzle versus cure on a MSLA mask — the &lt;a href=&#34;/posts/fdm-vs-resin-explained/&#34;&gt;earlier deep dive on how FDM and resin actually work&lt;/a&gt; covers it cleanly; this one is the workflow-and-decision post that goes after that.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Starlink: How a LEO Constellation Delivers Low Latency</title>
      <link>/posts/starlink-leo-constellation-low-latency/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/starlink-leo-constellation-low-latency/</guid>
      <description>&lt;p&gt;For thirty years &amp;ldquo;satellite internet&amp;rdquo; meant a half-second of latency, a price tag aimed at oil rigs, and a connection so painful you only used it when nothing else would reach you. Starlink broke every part of that sentence by changing one assumption: that satellites had to live at geostationary altitude, 35,786 km above the equator, where they hang still in the sky for the convenience of a fixed dish. Move the satellites down to roughly 550 km — sixty-five times closer — and the round-trip time at the speed of light collapses from over 500 milliseconds to under 10. Everything Starlink is, including its phased-array dish, its 53-degree orbital planes, its inter-satellite laser mesh, and its capacity headaches, falls out of that one altitude change. This post walks the physics of how 6,700-plus satellites at low Earth orbit produce a 25-millisecond connection to your laptop, what the dish on your roof is actually doing, where the architecture wins against fiber, and where it does not. There is no magic. There is a constellation, a clock, and a beam.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tech and Travel: Must-Haves and Dead Weight</title>
      <link>/posts/tech-and-travel-must-haves-and-dead-weight/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tech-and-travel-must-haves-and-dead-weight/</guid>
      <description>&lt;p&gt;Every traveler eventually arrives at the same uncomfortable realization, usually around night three of a two-week trip: half the tech they packed has not come out of the bag, the other half is doing twice the work, and the difference between the two is rarely what they expected before leaving. The lesson is not &amp;ldquo;pack less&amp;rdquo; — that is the conclusion every listicle reaches and it is incomplete — it is that &lt;em&gt;gear earns its slot in your bag the same way infrastructure earns its rack space&lt;/em&gt;: by serving a real, repeated problem cheaply in weight and volume. Everything else is either an expensive single-use comfort or, more often, dead weight you carry because past-you was afraid of an edge case you will not actually hit. This is an opinionated, by-category breakdown of what consistently pays for its slot and what consistently does not, written for the kind of traveler who treats a carry-on like a budget rather than a closet. The categories are roughly ordered by how much weight error in them costs you per day on the road.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Refrigeration Cycle</title>
      <link>/posts/the-refrigeration-cycle/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-refrigeration-cycle/</guid>
      <description>&lt;p&gt;The refrigerator in your kitchen, the air conditioner in your window, and the heat pump heating a modern house are not three inventions. They are one invention, built three ways, and the differences between them are almost cosmetic — which coil you point at the room, and whether you care about the cold end or the hot end. All three are &lt;strong&gt;vapor-compression&lt;/strong&gt; machines, and what they do is not &amp;ldquo;make cold.&amp;rdquo; Cold is not a substance you can manufacture; it is merely the absence of heat. What these machines actually do is &lt;strong&gt;pump heat&lt;/strong&gt; — they pick heat up from a place that is already cool and carry it, against its natural downhill direction, to a place that is already warm, the same way a water pump lifts water uphill. A refrigerator does not chill its contents so much as it relentlessly evicts their heat to your kitchen, which is why the back of the fridge is warm: that warmth is the heat that used to be in your food. Once you see the cycle as a heat &lt;em&gt;pump&lt;/em&gt; rather than a cold &lt;em&gt;generator&lt;/em&gt;, the whole thing snaps into focus, including the otherwise baffling fact that these machines can deliver several times more heat energy than the electricity they consume.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wi-Fi 7 and Multi-Link Operation</title>
      <link>/posts/wifi-7-and-multi-link-operation/</link>
      <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wifi-7-and-multi-link-operation/</guid>
      <description>&lt;p&gt;The marketing for Wi-Fi 7 leads with a number — up to 46 Gbps — that you will never see on any device you own, in any room you stand in, for the entire life of the standard. That number is the product of three multipliers stacked on top of each other under laboratory conditions: 320 MHz channels, 4096-QAM modulation, and a stack of spatial streams no client radio implements. The honest story of 802.11be is not about peak throughput at all. It is about a single architectural change — Multi-Link Operation, or MLO — that lets a device talk to an access point over two or three radio bands at once and treat them as one connection. That change does less for your top speed than the brochure implies and far more for the two things that actually make a wireless network feel good: latency and reliability. The IEEE finalized 802.11be in July 2025, so the spec is now fixed and the hardware is catching up to it. This is what is real, what is theater, and what it does for a home network you actually run.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cast Iron Seasoning Is Polymer Chemistry</title>
      <link>/posts/cast-iron-seasoning-is-polymer-chemistry/</link>
      <pubDate>Wed, 17 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cast-iron-seasoning-is-polymer-chemistry/</guid>
      <description>&lt;p&gt;A well-seasoned cast iron pan is not a pan with oil baked onto it. It is a pan with a thin, hard, glassy thermoset film chemically bonded to a passivated iron-oxide surface, and that film is no more &amp;ldquo;oil&amp;rdquo; than a finished epoxy is &amp;ldquo;resin.&amp;rdquo; Calling seasoning &amp;ldquo;polymerized fat&amp;rdquo; is technically correct but understates the point: what you are actually doing every time you wipe an oily paper towel on a hot skillet and put it back in the oven is running an industrial coating process — the same chemistry that paints a barn, hardens a linoleum floor, and yellows a Renaissance oil painting — except your reaction vessel is a frying pan and your initiator is a hot lump of iron. Every piece of folk wisdom about cast iron either makes sense as a consequence of that chemistry or is wrong. Once you see the film as a cross-linked polymer with measurable failure modes — brittleness, flaking, soft tackiness, uneven cure — the whole exercise stops being magic and becomes a process you can run, debug, and rescue.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cast Iron Seasoning Is Polymer Chemistry</title>
      <link>/posts/cast-iron-seasoning-polymer-chemistry/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cast-iron-seasoning-polymer-chemistry/</guid>
      <description>&lt;p&gt;The thing on a well-used cast iron skillet that makes food slide off is not oil, and it is not grease, and it is not a mysterious &amp;ldquo;patina&amp;rdquo; that accrues by faith. It is a &lt;strong&gt;polymer&lt;/strong&gt; — a hard, cross-linked, plastic-like film chemically built on the surface of the iron, grown by exactly the same chemistry that turns liquid linseed oil into the rock-hard finish on an old oil painting or a varnished floor. When you season a pan, you are not coating it; you are running a controlled polymerization reaction, converting small triglyceride molecules into a tough three-dimensional network bonded to the metal. Understanding that one fact dissolves nearly all of the folklore around cast iron at once: it explains why some oils work and others stay sticky, why you bake the pan past the point where the oil smokes, why thin coats succeed where thick ones turn to gum, why the &amp;ldquo;best&amp;rdquo; oil by hardness is also the one most likely to flake off in sheets, and why modern dish soap cannot hurt a properly cured pan. Seasoning is materials science that happens to take place in your oven.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CXL: Memory Pooling and the Disaggregated Server</title>
      <link>/posts/cxl-memory-pooling-disaggregated-server/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cxl-memory-pooling-disaggregated-server/</guid>
      <description>&lt;p&gt;In a modern server, memory is simultaneously the most expensive component and the most wasted one. DRAM can be half the bill of materials of a cloud instance, and yet fleet telemetry from every hyperscaler tells the same story: a large fraction of it sits stranded — provisioned to a machine that is CPU-bound and never touches it, while the machine next to it is memory-bound and thrashing to disk. The cause is architectural, not operational. Memory has always been welded to a single CPU socket, sized for that socket&amp;rsquo;s worst case, and invisible to every other socket in the rack. You cannot lend a spare 128GB from one server to its neighbor any more than you can lend it a spare lung. Compute Express Link is the technology built to break that weld. It is, not coincidentally, the same capacity tier that Intel&amp;rsquo;s 3D XPoint spent seven years and a billion dollars failing to sell as exotic silicon (&lt;a href=&#34;/posts/what-comes-after-nand/&#34;&gt;the post-mortem is in &amp;ldquo;What Comes After NAND&amp;rdquo;&lt;/a&gt;) — except CXL builds the tier out of ordinary DDR5 behind a cache-coherent link, which is exactly the lesson XPoint taught: when a job can be done by rearranging cheap incumbents, that beats inventing a new device.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DDR5 and Why Memory Latency Stopped Improving</title>
      <link>/posts/ddr5-memory-latency-wall/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ddr5-memory-latency-wall/</guid>
      <description>&lt;p&gt;Over the last twenty years, the capacity of a memory module grew by roughly 128 times and its bandwidth by about 20 times. In that same span, the one number that determines how long your CPU waits for a byte it did not see coming — the latency to fetch a random word out of DRAM — improved by a factor of about 1.3. Not 1.3 times per generation; 1.3 times &lt;em&gt;total&lt;/em&gt;, across two decades and three full generations of the standard. A random read from main memory took something like 13 to 15 nanoseconds in the DDR3 era, and it takes something like 13 to 15 nanoseconds today on DDR5, which is why a modern 5 GHz core that can retire several instructions per cycle will sit and stall for the equivalent of hundreds of instructions every time it misses cache and has to go to RAM. DDR5 is a genuinely large step forward — but every headline improvement it brought is about &lt;em&gt;bandwidth&lt;/em&gt; and &lt;em&gt;reliability&lt;/em&gt;, and almost none of it is about that stubborn first-byte latency, because the thing setting that latency is not the interface DDR5 redesigned. It is the analog physics of the memory cell, and the physics has not moved.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HDMI vs DisplayPort: The Protocol War at the End of Your Cable</title>
      <link>/posts/hdmi-vs-displayport/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hdmi-vs-displayport/</guid>
      <description>&lt;p&gt;There are two connectors on the back of a modern graphics card, they carry the same pixels to the same monitors, and the choice between them is one of the most quietly consequential decisions in consumer hardware — not because one makes a better picture, but because each is the visible end of a completely different political and economic machine. HDMI was built by a consortium of television and movie-studio companies to move protected content into your living room, governed by a closed specification and a per-device royalty. DisplayPort was built by VESA, the PC monitor standards body, to be royalty-free and to replace the tangle of VGA and DVI inside and outside the computer. The two have spent twenty years converging on the same job — packetized digital audio and video over a few high-speed differential pairs — while diverging on everything around it: who is allowed to implement it, which features get priority, and which device category each one quietly won. The cable at the end of your device is chosen for you by that history, and understanding it explains every frustration from &amp;ldquo;why won&amp;rsquo;t this daisy-chain&amp;rdquo; to &amp;ldquo;why can&amp;rsquo;t my Linux box do 4K120 over HDMI.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>How an Induction Cooktop Actually Works</title>
      <link>/posts/how-an-induction-cooktop-actually-works/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-an-induction-cooktop-actually-works/</guid>
      <description>&lt;p&gt;Every other cooktop ever built works by making something hot and then pressing your pan against it: a gas flame, a glowing radiant coil, a halogen element under glass. The heat is generated somewhere other than the food and then conducted, convected, and radiated toward it, losing a great deal along the way. An induction cooktop does something genuinely different and slightly uncanny: it generates the heat &lt;em&gt;inside the pan itself&lt;/em&gt;, directly in the metal, while the glass surface underneath stays cool enough to touch and only warms up afterward from the pan conducting heat back down into it. There is no hot element. The pan is the element. That single inversion — heat the load directly with a magnetic field instead of heating an intermediary and shipping the heat over — is why induction is both the most efficient way to cook on electricity and the one with the strangest list of quirks: it ignores your aluminum saucepan entirely, it buzzes at certain power levels, and it shuts off if you lift the pan. All of those behaviors fall straight out of the physics, and the physics is worth understanding.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NVMe-over-Fabrics: Block Storage at Near-Local Latency Over the Network</title>
      <link>/posts/nvme-over-fabrics/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nvme-over-fabrics/</guid>
      <description>&lt;p&gt;The single biggest reason iSCSI feels slow is not the network — it is that SCSI is a single-queue, command-tag-serialized protocol bolted to a transport designed for spinning disks. Every command goes through one queue with at most a handful of outstanding tags, every block read pays a SCSI-to-NVMe translation tax on the target, and every operation drags a 1980s session-layer state machine along for the ride. NVMe-over-Fabrics throws all of that out. It takes the same multi-queue, lockless submission/completion model that PCIe NVMe uses on a local bus and runs it over a network, so a remote SSD looks to the host like a local one with maybe 30 extra microseconds of latency.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pi: The Agentic Coding Harness That Refuses to Have Opinions</title>
      <link>/posts/pi-agentic-coding-harness/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pi-agentic-coding-harness/</guid>
      <description>&lt;p&gt;The dominant agentic coding tools of 2026 — Claude Code, Cursor, Codex — are products in the strong sense: they arrive with a worldview baked in, a large system prompt, an opinion about how you should plan, sub-agents, plan modes, and an ever-growing feature surface that you adapt yourself to. Pi, an open-source harness from the earendil-works team (the project of Mario Zechner, better known as badlogic), is the deliberate inverse. Its thesis is that a coding agent should be &lt;em&gt;plumbing&lt;/em&gt;, not a personality: a small, inspectable core of four tools and a unified model API, with everything else — planning, sub-agents, MCP, your house style — left to extensions you install or write. The bet underneath is specific and worth taking seriously: in an agentic loop, the scarcest resource is the context window, and the value lives in your repository, your docs, and your plans — not in the harness&amp;rsquo;s own prompt. Pi is built to keep the harness&amp;rsquo;s footprint small so that budget stays yours. Whether that is liberating or just homework is the real question, and the answer depends entirely on who you are.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Thunderbolt and USB4: How Tunneling Actually Works</title>
      <link>/posts/thunderbolt-usb4-tunneling/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/thunderbolt-usb4-tunneling/</guid>
      <description>&lt;p&gt;For thirty years a cable did exactly one thing. A VGA cable carried analog video and nothing else; a USB cable carried USB and nothing else; an Ethernet cable carried Ethernet. The protocol and the physical wire were welded together, and the connector on the end told you precisely what was inside. Thunderbolt and USB4 broke that assumption, and almost nobody noticed because the connector — USB-C — looks like just another port. What is actually happening inside a USB4 link is closer to a tiny packet-switched network than a cable: the wire carries an abstract, multiplexed fabric, and the real protocols you care about — PCIe, DisplayPort, USB3 — ride across it as &lt;em&gt;tunnels&lt;/em&gt;, encapsulated into fabric packets and reassembled transparently at the far end. Understanding that one shift, from dedicated wire to tunneled fabric, explains everything confusing about modern connectivity: why one port can drive a monitor and a GPU and a flash drive at once, why two identical-looking USB-C ports have wildly different capabilities, and why plugging in a dock can, in principle, read your encryption keys out of RAM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Water Filtration Compared: Carbon, RO, and Softeners</title>
      <link>/posts/water-filtration-carbon-ro-softeners/</link>
      <pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/water-filtration-carbon-ro-softeners/</guid>
      <description>&lt;p&gt;The single most expensive mistake people make with home water treatment is treating &amp;ldquo;filter&amp;rdquo; as one thing. It is at least three completely different physical processes, each of which removes a different category of stuff and is useless against the others. A carbon filter strips chlorine and organic molecules by &lt;em&gt;adsorption&lt;/em&gt; but leaves every dissolved mineral untouched. A water softener swaps your hardness ions for sodium by &lt;em&gt;ion exchange&lt;/em&gt; and removes nothing else — the water that comes out has the same total dissolved solids it went in with. Reverse osmosis pushes water through a membrane that blocks nearly everything dissolved, which is why it is the most thorough and also the one that wastes water and strips the minerals you might have wanted to keep. Buy the wrong one and you will spend money softening water whose problem was chlorine, or running RO on water whose only issue was limescale. The right way to choose is to stop thinking about &amp;ldquo;filtration&amp;rdquo; as a product category and start thinking about it as a set of distinct mechanisms matched to specific entries on your water report. This is the guide to which mechanism does what.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DiffusionGemma: When the LLM Stops Writing Left to Right</title>
      <link>/posts/diffusiongemma-explained/</link>
      <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/diffusiongemma-explained/</guid>
      <description>&lt;p&gt;Every large language model you have used writes the way you would if you could never revise: one token, then the next, each chosen with full knowledge of everything before it and zero knowledge of anything after. That single architectural commitment — autoregression — has defined the entire era of generative text, and it carries a hard physical cost: to produce N tokens you must run the model N times, in strict sequence, no matter how many GPUs you own. DiffusionGemma, released by Google in June 2026 as the first genuinely open-weight diffusion language model from a major lab, breaks that commitment. It generates text the way an image diffusion model generates a picture: start with a block of masked noise and iteratively &lt;em&gt;denoise&lt;/em&gt; it into coherent tokens, many at once, refining the whole block over a fixed number of passes. The result is roughly four times the throughput of the autoregressive Gemma 4 it is built on — and a measurable drop in quality, concentrated exactly where you would fear it. This is not a better Gemma. It is a different bet about how text should be generated, and it is now a bet you can run on a single consumer GPU.&lt;/p&gt;</description>
    </item>
    <item>
      <title>E Ink and the E-Reader: What the Screen Buys You, and What It Costs</title>
      <link>/posts/e-ink-and-ereaders/</link>
      <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/e-ink-and-ereaders/</guid>
      <description>&lt;p&gt;An e-reader is one of the few consumer gadgets whose defining feature is a thing it &lt;em&gt;cannot&lt;/em&gt; do: it cannot light up. Every benefit people attribute to a Kindle — the weeks of battery, the readability in direct sun, the way it disappears into the act of reading — and every limitation — the sluggish page turns, the ghosting, the near-uselessness for anything but linear text — flows from a single physical fact about the screen. An E Ink display is reflective and bistable. It throws ambient light back at you the way paper does, and it holds an image with zero power once that image is drawn. A phone screen is emissive and volatile: it manufactures its own light and must redraw itself sixty times a second or go black. These are not two points on a spectrum of &amp;ldquo;screen quality.&amp;rdquo; They are different machines doing different physics, and most arguments about e-readers go wrong by treating one as a worse version of the other. This post is about the machine underneath, and what it honestly does and does not buy you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Folding a NAS Into Your Daily Workflow: Linux, macOS, and Windows</title>
      <link>/posts/nas-workflows-linux-mac-windows/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nas-workflows-linux-mac-windows/</guid>
      <description>&lt;p&gt;A NAS is only as good as how invisibly it folds into the way you already work. The box itself is the easy part — you pick TrueNAS SCALE or OpenMediaVault, drop in some drives, and you have a blinking appliance on the network. The hard part, the part that decides whether the thing becomes load-bearing infrastructure or an expensive parking lot for files you forget about, is the integration: which protocol you mount on each operating system, whether those mounts survive a reboot and a laptop lid-close, how you separate &amp;ldquo;live storage I work off of&amp;rdquo; from &amp;ldquo;backup target I trust my life to,&amp;rdquo; and — the part almost everyone underestimates — how the network in between quietly decides which activities feel instant and which feel like wading through mud. Get those four things right and the NAS disappears into your workflow the way a good tool should. Get them wrong and you will fight it daily.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Candy Making and the Temperature of Sugar</title>
      <link>/posts/candy-making-and-the-temperature-of-sugar/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/candy-making-and-the-temperature-of-sugar/</guid>
      <description>&lt;p&gt;There is only one candy recipe. You dissolve sugar in water, you boil it, and the temperature you stop at decides whether you made a lollipop, a caramel, a piece of fudge, or a marshmallow. Everything else — the butter, the cream, the flavoring, the whipping — is detail layered on top of that single variable. The reason a candy thermometer is the one indispensable tool in the confectioner&amp;rsquo;s kit is that the temperature of boiling sugar syrup is not really a temperature reading at all. It is a moisture gauge. As water boils away the syrup gets more concentrated, its boiling point climbs, and the number on the thermometer tells you, with surprising precision, exactly how much water is left. Stop at 115 °C and you have a syrup that will set into something soft and chewy. Push to 150 °C and you have one that will cool into a hard, transparent glass. Same pot, same sugar, 35 degrees apart, two completely different materials.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creators Worth Following: A Trust Map for This Blog&#39;s Subjects</title>
      <link>/posts/creators-worth-following-a-trust-map/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/creators-worth-following-a-trust-map/</guid>
      <description>&lt;p&gt;The hardest part of learning anything technical in 2026 is not finding information — it is finding information you can trust. Every space this blog covers has a thick layer of creators on top of it, and the median one is an affiliate-link funnel dressed up as education: the thumbnail screams, the title promises a secret, and the actual content is a reskinned press release for whatever review unit showed up that week. Buried under that layer is a much smaller set of people who are genuinely rigorous, who show their methodology, who disclose their sponsors, and who will tell you when a popular product is bad or a popular technique is wrong. This is a map of that smaller set, organized by category and by platform, with a blunt note on each one&amp;rsquo;s incentives so you can calibrate rather than take my word for it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ECC for Flash: Hamming to LDPC</title>
      <link>/posts/ecc-for-flash-hamming-to-ldpc/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ecc-for-flash-hamming-to-ldpc/</guid>
      <description>&lt;p&gt;Raw NAND flash is, by any honest definition, broken hardware. A fresh TLC die fresh off the wafer will hand you pages with a handful of bit errors; the same die near the end of its rated life will hand you pages with hundreds of errors per kilobyte. No application could tolerate that, and no datasheet promises it directly. What the datasheet promises is an &lt;em&gt;uncorrectable&lt;/em&gt; bit error rate (UBER) of one error in 10^15 or 10^16 bits — a number that exists only because a layer of error-correcting code sits between the cell array and your data, turning a raw bit error rate (RBER) of around 10^-3 into a corrected error rate fourteen orders of magnitude lower. The entire economics of flash — denser cells, more bits per cell, lower cost per gigabyte — is a bet that ECC can keep absorbing the worsening physics. This post traces that ECC from the trivial parity bit through Hamming and BCH to the soft-decision LDPC codes that ship in every modern SSD, and connects it back to the millivolts of &lt;a href=&#34;/posts/nand-read-window-budget/&#34;&gt;read window&lt;/a&gt; that ECC ultimately spends its life fighting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Failure Analysis: From RMA to Root Cause</title>
      <link>/posts/failure-analysis-from-rma-to-root-cause/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/failure-analysis-from-rma-to-root-cause/</guid>
      <description>&lt;p&gt;A return is a hypothesis you have not tested yet. A customer ships back a part and writes &amp;ldquo;dead on arrival&amp;rdquo; or &amp;ldquo;intermittent reset under load,&amp;rdquo; and that sentence is a claim about physics you cannot see. Failure analysis is the discipline of converting that claim into a coordinate on a die, a mechanism with a name, and a change to a process that stops the next one from coming back. It is debugging, but the bug lives in silicon, mold compound, and solder, and the print statements are photons, heat, and electron-scattering contrast. The reason FA is hard is the same reason it is interesting: every good technique trades information for the integrity of the sample, and the most informative techniques are the ones that destroy the part. So FA is structured around a single inviolable rule. You spend non-destructive observation first, you localize before you cut, and you do not pour acid on your only piece of evidence until you have squeezed every photon and every milliamp of signal out of it intact.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Wafer Fab Works</title>
      <link>/posts/how-a-wafer-fab-works/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-wafer-fab-works/</guid>
      <description>&lt;p&gt;A wafer fab does something that has no parallel in any other industry: it manufactures structures a few atoms wide, billions of them per square centimeter, with near-zero defects, on a surface that must stay flatter than a continent and cleaner than an operating room, and it does this profitably at the scale of tens of thousands of wafers a month. The astonishing part is not that the structures are small. It is that the entire machine is built from a surprisingly short list of physical operations — coat a film, expose a pattern, develop it, etch it, deposit a new material, dope it, polish it flat, clean it, measure it — run not once but as a &lt;em&gt;loop&lt;/em&gt;, hundreds of times, each pass adding one more patterned layer to the stack. The fab is a layer-build engine. Understanding it means understanding the loop, the contamination control that lets the loop run at all, the months of cycle time the loop accumulates, and the twenty-billion-dollar capital structure that makes the loop turn at the leading edge. This post builds the fab from those primitives up.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Semiconductors Are Tested</title>
      <link>/posts/how-semiconductors-are-tested/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-semiconductors-are-tested/</guid>
      <description>&lt;p&gt;Every die that ships has been individually interrogated by a machine that costs more than a house, and the result of that interrogation — pass, bin 3, fail, retest — is the single fact that turns a slab of patterned silicon into a product you can buy. A fab produces &lt;em&gt;candidates&lt;/em&gt;. Test produces &lt;em&gt;parts&lt;/em&gt;. The gap between those two words is where billions of dollars and the entire credibility of a datasheet live. &lt;strong&gt;Test is not a quality-assurance afterthought bolted onto manufacturing; it is a co-equal manufacturing step whose cost, throughput, and statistical philosophy shape the chip&amp;rsquo;s price, its reliability, and what the vendor is legally and contractually promising you.&lt;/strong&gt; A modern part can spend a meaningful fraction of its total cost being measured, and the engineers who own that measurement spend their careers fighting two enemies that pull in opposite directions: the seconds of tester time that bleed margin on every unit, and the escaped defects that bleed reputation one field return at a time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NAND Interfaces: ONFI, Toggle, and the Speed Problem</title>
      <link>/posts/nand-interfaces-onfi-toggle-and-the-speed-problem/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nand-interfaces-onfi-toggle-and-the-speed-problem/</guid>
      <description>&lt;p&gt;For most of NAND flash&amp;rsquo;s history, the slow part was the cell. Pulling charge out of a floating gate, sensing it against a reference, and resolving which of sixteen voltage levels a QLC cell holds takes tens of microseconds, and that page-read time, &lt;code&gt;tR&lt;/code&gt;, dominated every datasheet conversation. That era is ending. Modern triple-level and quad-level NAND still has a &lt;code&gt;tR&lt;/code&gt; of roughly 50 to 90 microseconds, but the array reads a 16 KB page in one shot, and once that page sits in the on-die register the only thing standing between it and the controller is a parallel bus running at a fixed transfer rate. As that bus has crawled from 50 MB/s to 4.5 GB/s the math has inverted: for a large sequential read, the time spent shoveling bytes across the interface now rivals or exceeds the time spent reading the cells. The bottleneck moved off the silicon and onto the wire. This post is about that wire — the two standards that define it, the punishing signal-integrity physics that limits it, and why the industry&amp;rsquo;s answer is not &amp;ldquo;make the bus faster&amp;rdquo; so much as &amp;ldquo;put fewer things on each bus and build more buses.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>NAND Reliability Physics and Qual</title>
      <link>/posts/nand-reliability-physics-and-qual/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nand-reliability-physics-and-qual/</guid>
      <description>&lt;p&gt;There is exactly one physical fact you need to internalize before any NAND datasheet number makes sense: the same oxide layer you must violently push electrons through to write a cell is the oxide that has to quietly hold those electrons for years afterward. Programming and erasing damage the very barrier that retention depends on, so endurance and retention are not two independent specs — they are opposite ends of one budget, and every qualification standard in this space exists to pin down where on that budget a part is allowed to live. A drive rated for &amp;ldquo;600 TBW with one-year retention at 30C&amp;rdquo; is making a joint claim, and the only way to read it honestly is to understand the wear mechanism underneath. This post starts at the tunnel oxide, walks up through trap generation, stress-induced leakage current, detrapping, and the disturb taxonomy, and then turns to what JESD218 and JESD219 actually require, what they prove, what they conspicuously do not prove, and how the automotive AEC-Q100 grades change the math. By the end you should be able to look at a spec line and reconstruct the physics it is hiding.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NAS Drive Selection: Reusing the Disks You Already Have</title>
      <link>/posts/nas-drive-selection-and-drive-health/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nas-drive-selection-and-drive-health/</guid>
      <description>&lt;p&gt;The NAS arrived before the drives did. That is the normal order of operations for a homelab: you justify the chassis, then you look at the price of four or six brand-new NAS-rated drives and decide the pile of disks in the closet will do for now. The pile is the problem. It is a mix of drives pulled from old desktops, an external USB enclosure you cracked open, maybe a &amp;ldquo;surveillance&amp;rdquo; drive that came with a camera kit, and one survivor from a machine that died for unrelated reasons. None of them match. Some of them will quietly destroy your array&amp;rsquo;s performance, one of them might be lying about its own health, and at least one is the wrong &lt;em&gt;kind&lt;/em&gt; of drive in a way that does not show up until you try to rebuild after a failure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Power-Loss Protection</title>
      <link>/posts/power-loss-protection/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/power-loss-protection/</guid>
      <description>&lt;p&gt;An SSD that acknowledges a write has made you a promise: that data is now durable, and it will survive a power cut. The entire stack above the drive — the filesystem journal, the database WAL, the &lt;code&gt;fsync()&lt;/code&gt; your application blocked on — is built on the assumption that a completed write command means the bytes are safe. But inside the drive, the truth at the moment of acknowledgement is almost never that the data is on NAND. It is in a volatile DRAM write buffer, and the drive&amp;rsquo;s logical-to-physical map that knows where it went lives in DRAM too. Yank the power in that instant and, on a drive without proper protection, the acknowledged write evaporates and — far worse — the mapping metadata can be left torn, taking down data you wrote weeks ago. Power-loss protection is the small bank of capacitors and the carefully ordered firmware dance that turns that promise from a lie into the truth. This post is about what that machinery actually guarantees, what the marketing wording quietly excludes, and how to prove a drive does what its datasheet claims by cutting its power thousands of times and looking for the lies.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Semiconductor Yield Engineering</title>
      <link>/posts/semiconductor-yield-engineering/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/semiconductor-yield-engineering/</guid>
      <description>&lt;p&gt;A foundry can have the best transistor in the world and still lose money on every wafer. The transistor is a physics achievement; yield is the business. When two companies race to a new process node, the winner is almost never the one whose transistor switches a few picoseconds faster — it is the one that learns to make the same die with fewer fatal defects, faster, and recovers more good parts from every wafer it starts. Yield is the multiplier between &amp;ldquo;we can build this&amp;rdquo; and &amp;ldquo;we can sell this at a profit.&amp;rdquo; It converts a fixed, brutal per-wafer cost into a variable cost per &lt;em&gt;good&lt;/em&gt; die, and that conversion factor is where fortunes are made and lost. This post builds yield from first principles: what it is, the defect-density math that predicts it, why memory is structurally the most forgiving product in all of silicon, how binning turns a single design into a price ladder, and why the slow climb of the yield ramp — not the headline of &amp;ldquo;first silicon&amp;rdquo; — actually determines who controls a node.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sous Vide Is Just a PID Loop</title>
      <link>/posts/sous-vide-is-just-a-pid-loop/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sous-vide-is-just-a-pid-loop/</guid>
      <description>&lt;p&gt;A steak overcooks because heat does not know when to stop. Drop it in a 230 C pan and the surface races past well-done while the center is still raw, and the only tool a conventional cook has against that gradient is timing and nerve. Sous vide deletes the problem by changing the boundary condition: instead of applying a huge temperature difference and yanking the food out at the right instant, you submerge it in water held at &lt;em&gt;exactly&lt;/em&gt; the doneness temperature you want and let the whole piece equilibrate. The food cannot overcook because there is nowhere hotter for it to go. The center asymptotically approaches the setpoint and stops. That is the entire idea, and it is not really a cooking technique — it is a closed-loop control problem with a tasty output.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Flash Translation Layer</title>
      <link>/posts/the-flash-translation-layer/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-flash-translation-layer/</guid>
      <description>&lt;p&gt;Your SSD is lying to you, and the lie is the product. The operating system thinks it is talking to a disk — a flat array of fixed-size sectors you can overwrite in place, any one, any time, forever. NAND flash can do none of those things. You cannot overwrite a flash page; you must erase a much larger block first. You cannot erase a single page; erase only works on whole blocks of hundreds of pages at once. And every erase wears the cells out, so you cannot keep hammering the same location. The gap between the tidy disk the OS expects and the unruly flash that actually exists is bridged by a single, enormous piece of firmware running on the drive&amp;rsquo;s controller: the Flash Translation Layer. The FTL&amp;rsquo;s entire job is to maintain the fiction of a disk on top of a medium that behaves nothing like one, and how well it tells that lie determines whether your SSD is fast and durable or slow and dead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The NAND Commodity Cycle</title>
      <link>/posts/the-nand-commodity-cycle/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-nand-commodity-cycle/</guid>
      <description>&lt;p&gt;A NAND flash bit is one of the most sophisticated objects humanity manufactures at scale — a charge trap a few dozen nanometers wide, stacked hundreds of layers deep, read by inferring voltage thresholds at the edge of physical noise — and the market treats it exactly like a barrel of crude or a hog carcass. The price of that bit can fall 70% in eighteen months and then double in two quarters, not because anyone invented anything, but because too many fabs were built at the same time, or too few. This is the central, uncomfortable truth of the storage industry: the engineering is heroic, the economics are agricultural. NAND is a commodity, a bit is a bit, and the thing that actually decides which products ship and which companies survive is not lithography or layer count but where you happen to sit in a violent, multi-year supply-and-demand cycle that nobody controls and everybody loses to eventually. This post is about that cycle — why it exists, why it is structurally unavoidable, why it has ground the industry down to roughly five survivors, and how the 2022-2023 crash gave way to the AI-driven supply crunch that, as of mid-2026, has makers raising prices faster than at any point in living memory.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Thermodynamics of Cooking Meat</title>
      <link>/posts/the-thermodynamics-of-cooking-meat/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-thermodynamics-of-cooking-meat/</guid>
      <description>&lt;p&gt;A steak and a brisket are the same material — muscle, water, fat, and connective tissue — and they want almost exactly opposite treatment. The steak you sear hard and pull at 54 °C in eight minutes. The brisket you hold at 95 °C for twelve hours. If you cook the steak like the brisket you get gray shoe leather; if you cook the brisket like the steak you get a slab you cannot chew. The reason is not culinary tradition or taste preference. It is thermodynamics: the two cuts have different ratios of the proteins that toughen on heating versus the ones that dissolve, and &amp;ldquo;cooking&amp;rdquo; is nothing more than driving each of those proteins across its denaturation temperature at the right rate. Once you see meat as a stack of proteins that each change phase at a known temperature, every rule in the kitchen — rest the roast, don&amp;rsquo;t cook chicken rare, sear for flavor not for &amp;ldquo;sealing in juices&amp;rdquo; — stops being folklore and becomes a consequence of heat moving through a solid.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zoned Storage and FDP</title>
      <link>/posts/zoned-storage-and-fdp/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zoned-storage-and-fdp/</guid>
      <description>&lt;p&gt;Every conventional SSD runs a small lie. The host writes logical block 7 today and logical block 7 again tomorrow, treats the drive as an infinite scratchpad of overwritable sectors, and the drive quietly does an enormous amount of work to maintain that illusion. NAND cannot be overwritten in place; it can only be programmed sequentially within a block and erased a whole block at a time. The translation layer that bridges that gap is the &lt;a href=&#34;/posts/the-flash-translation-layer/&#34;&gt;flash translation layer&lt;/a&gt;, and it is expensive: it burns DRAM holding the logical-to-physical map, reserves a slice of the drive&amp;rsquo;s raw capacity you never see, and silently rewrites your data in the background to reclaim space. Zoned storage is the argument that the lie is not worth paying for. If the host already knows which data belongs together and when it will die, it can place that data itself, hand the drive a write pattern that matches the physics, and let most of the FTL&amp;rsquo;s machinery evaporate. ZNS, FDP, and the older world of SMR hard drives are three points on that same spectrum, trading host effort for device efficiency in different proportions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>3D NAND Architecture: Building Memory Sideways, Then Up</title>
      <link>/posts/3d-nand-architecture/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/3d-nand-architecture/</guid>
      <description>&lt;p&gt;For forty years, making memory denser meant making it smaller. Planar NAND rode lithography from micron-scale cells down to 15 nanometers, and then — almost uniquely in semiconductors — the industry stopped shrinking, turned the structure on its side, and started building &lt;em&gt;up&lt;/em&gt; instead. Modern 3D NAND is not planar NAND with more layers; it is a different device (charge-trap instead of floating-gate, in most cases), a different transistor geometry (gate-all-around cylinders), a different manufacturing economics (etch- and deposition-bound instead of litho-bound), and a different scaling law (add layers, not shrink features). It is also, quietly, the most aggressive vertical manufacturing humanity does: a current-generation die etches trillions of holes with aspect ratios that would embarrass an oil-drilling operation, through more than 300 alternating films, and lands every one of them within nanometers. This post explains how the structure works, why each architectural choice was forced, and what the choices cost — from first principles to the level where vendor roadmap slides start making sense.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Burnout, Mechanistically</title>
      <link>/posts/burnout-mechanistically/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/burnout-mechanistically/</guid>
      <description>&lt;p&gt;&amp;ldquo;Burnout&amp;rdquo; is the rare technical term that got worse by going mainstream. In the research literature it has a reasonably specific meaning, a standard instrument, a forty-year evidence base, and a set of predictors that are genuinely useful for deciding what to fix. In the discourse, it has become a synonym for &amp;ldquo;tired,&amp;rdquo; a personal failing to be yoga&amp;rsquo;d away, or — worst — a pseudo-endocrine condition involving depleted adrenal glands. Engineers deserve the actual model, because engineers are unusually exposed (on-call, interrupt-driven work, low-autonomy ticket mills) and unusually well-equipped to use it: burnout, as the evidence describes it, is a systems problem with measurable dimensions, identifiable inputs, and known failure signatures. This post is the mechanistic tour — including honest flags on everything the field still gets wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Caffeine Pharmacokinetics for Engineers</title>
      <link>/posts/caffeine-pharmacokinetics-for-engineers/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/caffeine-pharmacokinetics-for-engineers/</guid>
      <description>&lt;p&gt;You have spent more time tuning JVM flags than tuning the only stimulant most engineers consume every day, and the irony is that the JVM is documented and your body is not. Caffeine is the most-used psychoactive drug on earth, the foundation of every overnight deploy and most of the world&amp;rsquo;s interesting code, and almost nobody who relies on it can articulate what it does after it leaves the cup. That gap is fixable. Caffeine has clean first-order kinetics, a well-characterized molecular target, a documented genetic axis that explains why your coworker can drink an espresso at 9 PM and you cannot, and an inverted-U dose-response curve that explains why the third cup makes you a worse engineer rather than a better one. The aim here is not to prescribe or moralize. It is to give you the model so you can dose yourself like the system you actually are.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chip Export Controls: Why You Can&#39;t Buy an H100 in Shanghai</title>
      <link>/posts/chip-export-controls-why-you-cant-buy-an-h100-in-shanghai/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/chip-export-controls-why-you-cant-buy-an-h100-in-shanghai/</guid>
      <description>&lt;p&gt;An H100 is a commodity. It is a tray of silicon you can buy on a purchase order, rack in a 19-inch chassis, and bill by the hour. It is also, by US law, a controlled munition in everything but name — a part you cannot legally sell into the world&amp;rsquo;s second-largest economy without a license you will almost certainly not get. The gap between those two facts is where a remarkable amount of money, engineering, and diplomatic energy now lives. If you train models, rent GPUs, or just buy them, the price and availability you see have been shaped less by TSMC&amp;rsquo;s yield and more by a few paragraphs of regulation written in Washington and revised, on average, about twice a year.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Desktop CNC Routers: Subtractive for the Home Shop</title>
      <link>/posts/desktop-cnc-routers-subtractive-home-shop/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/desktop-cnc-routers-subtractive-home-shop/</guid>
      <description>&lt;p&gt;If you came to fabrication through a 3D printer, the CNC router is the next obvious machine and the most likely one to humble you. A printer is a forgiving thermoplastic extruder with a slicer that hides almost every decision; a router is a spinning carbide blade attached to a rigid frame, driven by toolpaths you wrote, into stock you clamped down yourself, with chips flying and a tolerance for mistakes measured in seconds. There is no slicer that hides the math, no auto-bed-leveling to save a bad setup, and no &amp;ldquo;just reprint it&amp;rdquo; when a $30 endmill snaps because you forgot to check the chip load. Everything that the FDM workflow papers over — toolpath strategy, workholding, cutter selection, depth of cut, feed rate, spindle speed, dust extraction, noise, fire — comes back as a non-optional knob. The reward, when you get it right, is a class of part a printer cannot make: stiff, dimensionally accurate, machinable in real materials, and finished to a quality that does not scream &amp;ldquo;hobby.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fermentation as Bioprocess Control</title>
      <link>/posts/fermentation-as-bioprocess-control/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fermentation-as-bioprocess-control/</guid>
      <description>&lt;p&gt;A jar of fermenting cabbage is a bioreactor running an uncontrolled, open-loop microbial workload, and the only reason it reliably produces sauerkraut instead of food poisoning is that you have rigged the initial conditions so that the organisms you want outcompete the ones that would kill you. That is the entire trick, and it is pure process engineering. You are not &amp;ldquo;letting it ferment.&amp;rdquo; You are configuring a selective environment — salt, anaerobiosis, temperature, starting pH — such that a specific succession of bacteria boots up, drives the system to a stable acidic steady state, and locks out every pathogen on the way down. Nobody is stirring it. Nobody is dosing it. The control is entirely in the setup, which makes fermentation the cleanest example in your kitchen of a system that succeeds or fails on its initial conditions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fusion, Honestly</title>
      <link>/posts/fusion-honestly/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fusion-honestly/</guid>
      <description>&lt;p&gt;Fusion is the energy source that has been thirty years away for seventy years, and the joke is starting to feel unfair — because the physics genuinely is moving now, faster than at any point in the field&amp;rsquo;s history. But &amp;ldquo;moving&amp;rdquo; and &amp;ldquo;almost here&amp;rdquo; are different claims, and the gap between them is exactly where press releases live. In December 2022 a US laser facility achieved &amp;ldquo;ignition&amp;rdquo; and the headlines said fusion had produced more energy than it consumed. That statement is true under one specific definition of &amp;ldquo;consumed&amp;rdquo; and wildly false under the definition a grid operator would use. Understanding which is which — separating the real, hard-won physics milestone from the accounting sleight-of-hand the headline performed — is the whole game when reading fusion news. This post is the honest version: what the milestones actually proved, what they didn&amp;rsquo;t, why the remaining problems are materials and engineering rather than physics, and what timeline a numerate skeptic should actually hold. Fusion is real, it is coming, and it is further away than the funding announcements imply. All three of those are true at once.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Heat Pumps: Carnot in Your Garage</title>
      <link>/posts/heat-pumps-carnot-in-your-garage/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/heat-pumps-carnot-in-your-garage/</guid>
      <description>&lt;p&gt;A resistance heater turns one joule of electricity into one joule of heat. A heat pump turns one joule of electricity into three or four joules of heat in your house, by moving the other two or three from outside, even when outside is twenty degrees Fahrenheit and the marketing copy looks like it is lying. It is not lying. The second law of thermodynamics imposes a ceiling on how much heat you can move per joule of work spent moving it, that ceiling depends on the temperature difference you are pushing against, and modern vapor-compression hardware now lives close enough to that ceiling that the gap between physics and the unit on the side of the house is mostly a sales tax and a refrigerant choice. The reason heat pumps suddenly went from &amp;ldquo;great in San Diego&amp;rdquo; to &amp;ldquo;fine in Maine&amp;rdquo; in about a decade is not magic and it is not subsidy. It is variable-speed inverter compressors, vapor injection, electronic expansion valves, and a regulatory shove away from R-410A, all stacked on a cycle Sadi Carnot would recognise in 1824. If you can read a refrigeration P-h diagram you can buy a heat pump without being lied to, and if you can do a Manual J load calculation you can install one that actually works in February. Everything else — the COP graphs, the rebate calculus, the homelab waste-heat fantasy — is downstream of those two skills.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Automatic Transmissions Work</title>
      <link>/posts/how-automatic-transmissions-work/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-automatic-transmissions-work/</guid>
      <description>&lt;p&gt;The automatic transmission is the most computationally dense mechanical assembly most people own, and almost nobody knows what is inside it. A modern eight-speed lives between a kilowatt-class heat source and a road surface, has to translate a single rotating input into eight forward ratios plus reverse without ever opening a clutch the driver can feel, manages oil at pressures comparable to a hydraulic press, and increasingly does all of that under the supervision of a microcontroller running adaptive algorithms that learn the driver&amp;rsquo;s habits. Strip the casing off a ZF 8HP or a Toyota Aisin AA80E and what you find is a stacked set of planetary gearsets, a torque converter that is half fluid pump and half clutch, a hydraulic logic board the size of a paperback book with dozens of solenoids welded into it, and a control module that is structurally identical to anything you would call an embedded system. It is a mechanical computer that predates microcontrollers by forty years and got a brain transplant in the 1990s, and once you understand how the pieces interact the whole device stops looking like a black box and starts looking like a perfectly ordinary control problem solved with steel and oil.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Nuclear Reactors Work</title>
      <link>/posts/how-nuclear-reactors-work/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-nuclear-reactors-work/</guid>
      <description>&lt;p&gt;A nuclear reactor is a machine for holding a number at exactly 1.000. The number is the neutron multiplication factor — how many neutrons from this generation of fission events survive to cause the next generation — and everything about reactor design is in service of keeping it there: the geometry of the core, the chemistry of the coolant, the metallurgy of the fuel, the control systems, and several layers of physics that push the number back toward 1 when it drifts. What makes reactors interesting to an engineer is not that they&amp;rsquo;re exotic; it&amp;rsquo;s that they are the most consequential feedback-control problem ever productized, with thermal margins measured in minutes and consequences measured in decades. And the punchline of the whole field, which this post will earn by the end: the physics was essentially solved by 1960, the safety engineering by 2000, and what actually determines whether nuclear power grows or dies is interest rates on construction loans.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Standards Bodies Actually Work</title>
      <link>/posts/how-standards-bodies-actually-work/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-standards-bodies-actually-work/</guid>
      <description>&lt;p&gt;Every time you open a socket, join a Wi-Fi network, or plug in a cable, you are trusting a document written by a committee you have never met, under rules you have never read, funded by companies whose interests do not align with yours. That this works at all is one of the quiet miracles of engineering. That it works &lt;em&gt;unevenly&lt;/em&gt; — beautifully for email, miserably for USB naming, expensively for cellular — is the part worth understanding, because the quality of a standard is downstream of the institution that produced it, and those institutions could not be more different from one another.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Laser Cutters for the 3D Printing Crowd: Subtractive for People Who Think Additive</title>
      <link>/posts/laser-cutters-for-the-3d-printing-crowd/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/laser-cutters-for-the-3d-printing-crowd/</guid>
      <description>&lt;p&gt;If you own a 3D printer, you already understand the maker-tool mental model: a digital design becomes a physical object, the machine is fussy, the consumables are real money, and the first month is a humbling sequence of failed jobs. A laser cutter slots into that mental model neatly — and then it cuts in the opposite direction. Where the printer adds material layer by layer to build up a part, the laser removes material from a sheet in seconds. The two machines disagree about almost everything: speed, geometry, materials, fixturing, design rules. That disagreement is exactly why owning both is so productive. The kinds of parts a 3D printer makes badly are usually the kinds a laser makes easily, and vice versa.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mechanical Watches: Precision Engineering You Can Wear</title>
      <link>/posts/mechanical-watches-precision-engineering-you-can-wear/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mechanical-watches-precision-engineering-you-can-wear/</guid>
      <description>&lt;p&gt;A mechanical watch is the only piece of consumer machinery most people will ever own that runs continuously, unattended, for years, at a duty cycle of 100 percent, with a precision floor that would have been considered an act of magic in 1750. It does this with no batteries, no firmware, no telemetry, and no over-the-air updates. The energy source is your wrist. The clock signal is a tiny piece of metal vibrating against a spring at a fixed frequency. The output is an angular position that, if everything has gone well, differs from civil time by a handful of seconds per day. Every part has been engineered for tolerances measured in microns and lifetimes measured in decades. Then, in 1969, a Japanese company shipped a quartz watch that was two orders of magnitude more accurate, cost a tenth as much, and required no skill to manufacture. The fact that mechanical watches still exist — and command higher prices than ever — is one of the more interesting case studies in technology disruption that engineers should sit with. Not because the mechanical watch won, but because of how thoroughly it lost on the spec sheet and how completely that turned out not to matter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NAND Trim: Calibrating Flash Memory at the Factory</title>
      <link>/posts/nand-trim-calibrating-flash-at-the-factory/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nand-trim-calibrating-flash-at-the-factory/</guid>
      <description>&lt;p&gt;A NAND flash die is sold as a digital product, but nothing inside it is digital. Storing a bit means parking a few hundred electrons on an insulated electrode; reading it back means comparing a transistor&amp;rsquo;s threshold voltage against a reference and hoping the distributions haven&amp;rsquo;t smeared into each other. Every voltage, every pulse width, every sense timing involved in that dance is generated by analog circuits — charge pumps, DACs, regulators, oscillators — and analog circuits built on a modern process vary. Die to die, wafer to wafer, lot to lot, layer to layer within a single 3D stack. &lt;strong&gt;Trim is the set of per-die calibration constants that absorbs this variation.&lt;/strong&gt; It is the reason two QLC die from opposite edges of a wafer, with measurably different physics, both meet the same datasheet. If you are new to NAND development, trim is the layer everyone around you keeps referencing and nobody has written down in one place. If you are about to own trim settings, the second half of this post is the detail you will actually need.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Open-Source Licensing, Actually Explained</title>
      <link>/posts/open-source-licensing-actually-explained/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/open-source-licensing-actually-explained/</guid>
      <description>&lt;p&gt;Almost every engineer ships other people&amp;rsquo;s code, and almost none of them have read the licenses that govern it. This works right up until it doesn&amp;rsquo;t: until a lawyer asks whether your product can be distributed, until an acquirer&amp;rsquo;s due-diligence team finds AGPL code in your closed-source backend, until the database you built a business on relicenses out from under you and you have to decide overnight whether to follow it, fork it, or rip it out. Open-source licensing is not a legal curiosity to delegate — it is a set of engineering constraints that determine what you are allowed to build, ship, and keep private, and the constraints are encoded in maybe a dozen licenses you can actually learn. The good news is that the landscape is far more comprehensible than its reputation suggests: there are two big ideas (permissive and copyleft), one wrinkle that the cloud era exposed (the SaaS loophole), and a recent wave of relicensing dramas that, once you understand the mechanics, all tell the same story. This post is the working engineer&amp;rsquo;s map — what each license actually obligates you to do, why the industry has been at war over licensing since 2018, and a checklist for not getting burned.&lt;/p&gt;</description>
    </item>
    <item>
      <title>QLC, PLC, and the Density Endgame</title>
      <link>/posts/qlc-plc-density-endgame/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/qlc-plc-density-endgame/</guid>
      <description>&lt;p&gt;There are two ways to make a NAND die hold more data: build more cells, or make each cell hold more bits. The first path — 3D stacking — costs etch and deposition. The second path costs nothing physical at all: the cell that stores two voltage states can, with sufficient nerve, store sixteen. No new layers, no new fab tools, just firmware, trims, and audacity. That free lunch is why bits-per-cell has crept relentlessly upward — SLC, MLC, TLC, QLC, with PLC perpetually auditioning — and the catch is one of the cleanest asymmetries in engineering: &lt;strong&gt;the gain is linear and the pain is exponential.&lt;/strong&gt; Each added bit increases capacity by a shrinking fraction while doubling the number of states squeezed into a voltage window that does not grow. QLC is the current frontier of that bargain, PLC is its speculative edge, and understanding exactly where the math bites is the difference between deploying QLC where it shines and discovering its weaknesses in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sleep Architecture and On-Call: The Engineer&#39;s Body on Rotating Shifts</title>
      <link>/posts/sleep-architecture-and-on-call/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sleep-architecture-and-on-call/</guid>
      <description>&lt;p&gt;On-call work asks engineers to do something the human body was not designed to do: become competent at solving novel problems in the seconds after being yanked out of slow-wave sleep at 3:47 AM. Every other part of the discipline gets engineered. We tune autoscalers, balance shards, version our APIs, write postmortems. But the substrate running the postmortem — a 5&#39;8&amp;quot; sack of water with a circadian oscillator wired to sunlight — is treated as a constant. It is not a constant. It is the most non-linear, state-dependent system in the entire stack, and ignoring its physics produces the same kind of outage that ignoring the physics of TCP produces: invisible until it explodes, then catastrophic, then blamed on the wrong layer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Software Patents for Working Engineers</title>
      <link>/posts/software-patents-for-working-engineers/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/software-patents-for-working-engineers/</guid>
      <description>&lt;p&gt;Most engineers read patents wrong, because patents are written to be read wrong. The title is marketing. The abstract is marketing. The drawings are decoration. The forty paragraphs describing &amp;ldquo;one embodiment of the present invention&amp;rdquo; are deliberately broad smoke. The only part of a patent with legal force is the numbered list of claims at the very end — and claims are read under rules so specific that two patents with identical titles can have completely different scope. You will interact with this system whether you want to or not: your employment contract almost certainly contains an invention assignment clause, your employer may dangle filing bonuses at you, your side project could receive a demand letter, and the prior art that kills a bad patent might be a blog post you wrote. This is the working engineer&amp;rsquo;s guide to a legal system that regulates your output.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Solar PV: From Photon to Inverter</title>
      <link>/posts/solar-pv-from-photon-to-inverter/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/solar-pv-from-photon-to-inverter/</guid>
      <description>&lt;p&gt;A solar panel is a semiconductor device — the same PN junction physics as the diode on your bench and the transistors in your CPU, manufactured by the square kilometer and pointed at a fusion reactor 150 million kilometers away. That&amp;rsquo;s the whole trick, and it&amp;rsquo;s worth holding onto, because it explains both of solar&amp;rsquo;s defining facts. The first: photovoltaics rode the same learning curves as the rest of the semiconductor industry, which is why module prices fell roughly 99% in four decades and solar became, by levelized cost, the cheapest electricity humans have ever produced. The second: it is bounded by hard physics — a band gap doesn&amp;rsquo;t negotiate — and by a grid integration problem that gets worse precisely as solar succeeds. This post runs the full stack: photon to junction, junction to panel, panel to inverter, inverter to grid, and grid to your payback spreadsheet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Space Weather: When the Sun Attacks Your Infrastructure</title>
      <link>/posts/space-weather-when-the-sun-attacks-your-infrastructure/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/space-weather-when-the-sun-attacks-your-infrastructure/</guid>
      <description>&lt;p&gt;The Sun is not a steady lamp. It is a magnetically violent ball of plasma that periodically hurls billions of tons of charged matter directly at Earth at millions of kilometers per hour, and when one of those clouds connects with our magnetic field, it induces currents in every long conductor on the planet — power lines, pipelines, undersea cables, railway signaling — that those conductors were never designed to carry. For most of human history this did not matter, because we had no long conductors and no electronics to fry. We built a civilization made almost entirely of things that space weather damages, and we did most of that building during a stretch of relatively mild solar behavior, which means our worst-case planning rests on storms we have mostly only read about. In May 2024 the Sun delivered the strongest geomagnetic storm in twenty years and grounded GPS-guided tractors across the American Midwest during planting season, costing an estimated half a billion dollars. That was not the big one. This post is about what space weather actually is, the specific ways it attacks the infrastructure stack, the historical events that calibrate the threat, and the genuinely thin layer of monitoring and operational response standing between a routine storm and a continental blackout.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Aquarium as a Production System</title>
      <link>/posts/aquarium-as-a-production-system/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aquarium-as-a-production-system/</guid>
      <description>&lt;p&gt;A reef aquarium is the most unforgiving production system most engineers will ever operate, and almost nobody who runs one thinks of it that way. It is a closed bioreactor holding a few hundred liters of artificial seawater, running 24/7/365 with no maintenance window, where the workload is alive and cannot be restarted from a snapshot. The water chemistry drifts continuously and must be held inside tolerances measured in parts per million. A power outage is an incident with a clock measured in hours before livestock dies. A single stuck float switch can put twenty liters of water on your floor or boil a heater dry. The blast radius of a bad change is a tank full of animals that took years to establish and cannot be re-provisioned from a Git repo. Every concept a platform engineer already owns — dependency ordering, monitoring and alerting, closed-loop control, redundancy, fail-safe defaults, capacity planning, blameless incident response — maps onto reefkeeping with almost suspicious precision. This post treats the tank as exactly what it is: an always-on system with a strict SLA, an angry pager, and a workload that does not tolerate downtime.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Espresso Machine Is a Control System</title>
      <link>/posts/espresso-machine-control-system/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/espresso-machine-control-system/</guid>
      <description>&lt;p&gt;Most engineers walk past espresso as a category of expensive ritual: dial, tamp, bar talk about beans. That framing buries what is actually happening on the counter. A modern espresso machine maintains a water temperature setpoint near 93 degrees Celsius against a heating element that pulses kilowatts of power into a small thermal mass, delivers nine bars of differential pressure across a load that changes its own resistance during the shot, and does all of it in a 25 to 35 second window where steady state never arrives. Two setpoints, one strongly nonlinear plant, no time to converge. It is one of the cleanest, cheapest, most instrumentable closed-loop control problems an engineer will ever encounter outside of work, and the home barista community has spent twenty years independently rediscovering every concept in a process control textbook — PID tuning wars, feedforward, model-predictive shot profiles, and a thriving open-source firmware scene running on STM32 microcontrollers. Once you see the espresso machine as a plant with a sensor, an actuator, a setpoint, and a disturbance, the entire forum culture stops looking like superstition and starts looking exactly like reading vendor benchmarks for storage gear.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Read Window Budget: Margin Accounting in NAND Design</title>
      <link>/posts/nand-read-window-budget/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nand-read-window-budget/</guid>
      <description>&lt;p&gt;NAND design has a single master currency, and it is measured in millivolts. A flash cell stores data as a threshold voltage, reads are comparisons against reference levels, and the entire reliability story of a die compresses into one question: how much empty space exists between adjacent voltage distributions, and what is allowed to eat it? That empty space is the read window, the accounting of who gets to consume it is the read window budget (RWB), and once you see NAND through this lens, every datasheet number, every qual test, and every field failure reorganizes itself into entries in one ledger. Endurance ratings are a statement about how much budget cycling is allowed to burn. Retention specs are a statement about how much budget charge leakage may consume. ECC strength is the size of the overdraft facility. This post builds the budget from physics up — accessible if you&amp;rsquo;ve never touched flash beyond an SSD — and finishes at the level of detail you&amp;rsquo;d need to argue about margin allocation in a design review.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Science of Learning for Technical Skills</title>
      <link>/posts/science-of-learning-for-technical-skills/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/science-of-learning-for-technical-skills/</guid>
      <description>&lt;p&gt;Engineers are professional learners who have mostly never studied how learning works. The half-life of a technical skill keeps shrinking — the stack you mastered five years ago is a legacy line item today — and yet the methods most of us use to acquire new skills are the same ones we used to cram for exams at nineteen: reread the docs, highlight the PDF, watch the video again, follow the tutorial, feel a warm sense of familiarity, and forget 70% of it within a week. This is not a personal failing. It is the predictable output of a brain that confuses &lt;em&gt;recognition&lt;/em&gt; with &lt;em&gt;recall&lt;/em&gt;, running study techniques that a century of cognitive science has measured and found nearly worthless. The same literature also identifies what does work — retrieval practice, spacing, interleaving, effortful difficulty — and the gap between the two sets of techniques is not subtle. In controlled studies it is routinely a 50–150% difference in retention. For someone grinding toward a CCNA, ramping onto Kubernetes, or learning Rust on the side, that gap is the difference between six months and eighteen. This post walks through the actual evidence — Roediger and Karpicke on testing, Ebbinghaus and his modern replicators on forgetting, Dunlosky&amp;rsquo;s landmark review, Bjork on desirable difficulties, Ericsson on deliberate practice — and then builds it into a workflow that fits around standups, pages, and a family.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Traeger Grills: Fixing, Hacking, and Improving</title>
      <link>/posts/traeger-grill-fixing-hacking-improving/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/traeger-grill-fixing-hacking-improving/</guid>
      <description>&lt;p&gt;A Traeger is not a grill in the way a Weber kettle is a grill. It is an embedded control system — a feedback loop with a temperature sensor, three actuators, and a microcontroller — that happens to produce smoked meat as its output. That framing matters, because once you see the machine for what it is, three things follow. First, every failure mode becomes diagnosable: there are only four components in the loop, and each fails in a characteristic way. Second, the machine becomes improvable: a control loop with a slow sensor and a coarse actuator can always be tuned, and a community of people with soldering irons has spent fifteen years doing exactly that. Third, the cloud dependence of the newer WiFIRE models stops looking like a feature and starts looking like what it is — a remote dependency injected into a device whose entire job is to hold 225°F for fourteen hours while you sleep.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wearable Sensor Accuracy: What Your Watch Can and Cannot Measure</title>
      <link>/posts/wearable-sensor-accuracy-what-your-watch-can-and-cannot-measure/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wearable-sensor-accuracy-what-your-watch-can-and-cannot-measure/</guid>
      <description>&lt;p&gt;Your watch displays a number with three significant figures, animated by a confident little graphic, and you read it like a fact. The number is downstream of a green LED bouncing photons off the back of your wrist, an accelerometer averaging itself over a window, and three or four machine-learning models trained on a population that probably doesn&amp;rsquo;t look like you doing activities that probably aren&amp;rsquo;t what you&amp;rsquo;re doing. Some of those numbers are honest; the device is measuring a real physical quantity with a tight bound on its error. Others are model output dressed up as measurement, the kind of thing a metrologist would call a &amp;ldquo;derived estimate&amp;rdquo; and would put a wide error bar around. Engineers spend their careers learning to distinguish a measured quantity from a fitted one in the systems they build, then forget the distinction the moment a piece of consumer tech promises to quantify their bodies. This post is about putting that distinction back where it belongs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What Comes After NAND?</title>
      <link>/posts/what-comes-after-nand/</link>
      <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/what-comes-after-nand/</guid>
      <description>&lt;p&gt;The graveyard of NAND killers is now large enough to draw conclusions from. Over two decades, a procession of technologies arrived with credible physics, real silicon, and confident roadmaps — and every one of them is either dead, retreated into an embedded niche, or still &amp;ldquo;two generations from volume.&amp;rdquo; The most instructive corpse is Intel and Micron&amp;rsquo;s 3D XPoint: a genuinely superior memory by most physical measures, backed by two giants, productized for seven years, and killed anyway. Its failure was not physics. It was a precise demonstration of why the question &amp;ldquo;what replaces NAND?&amp;rdquo; is mostly malformed — because in memory markets, &lt;em&gt;better&lt;/em&gt; doesn&amp;rsquo;t beat &lt;em&gt;cheaper-and-good-enough&lt;/em&gt;, and nothing on Earth is cheaper per bit than NAND while NAND keeps improving. This post does the post-mortem properly, assesses each surviving candidate without vendor optimism, and ends where the evidence points: the post-NAND future is mostly NAND, rearranged.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Backtesting Frameworks and the Ways Backtests Lie</title>
      <link>/posts/backtesting-frameworks-how-backtests-lie/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/backtesting-frameworks-how-backtests-lie/</guid>
      <description>&lt;p&gt;Every quant strategy starts with a backtest that looks extraordinary. Then it hits live markets and bleeds. The gap between paper performance and live performance is not bad luck — it is the predictable consequence of a catalogue of biases, most of which are invisible to the practitioner running the test. Backtesting frameworks differ meaningfully in how easy they make it to introduce each failure mode, but no framework eliminates them. The job is to understand the failure modes deeply enough to hunt them down yourself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Battery Chemistry Compared: LiFePO4, NMC, and Lead-Acid</title>
      <link>/posts/battery-chemistry-lifepo4-nmc-lead-acid/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/battery-chemistry-lifepo4-nmc-lead-acid/</guid>
      <description>&lt;p&gt;The marketing around batteries has inverted cause and effect so thoroughly that most engineers pick a chemistry the same way they pick a paint color: by vibe and brand familiarity. LiFePO4 is popular because it is popular; NMC dominates EVs because the specs look good on a slide; lead-acid lingers because it is cheap and it works and nobody wants to explain to the finance department why they are changing something that was fine. All three of those decisions can be correct, but none of them engages with the actual constraint, which is electrochemistry. The voltage, cycle life, thermal behavior, and degradation mode of a cell are not marketing choices — they are thermodynamic and structural consequences of what is happening at the electrode surface on every charge and discharge. Once you understand what is physically happening inside a cell, the trade-offs stop looking arbitrary. This post works through that chemistry for all three major chemistries and maps it directly onto the use cases that matter most in homelab, solar, and embedded power design.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a Paper-Trading Bot with the Alpaca API</title>
      <link>/posts/paper-trading-bot-alpaca-api/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/paper-trading-bot-alpaca-api/</guid>
      <description>&lt;p&gt;Every automated trading tutorial ends the same way: a Jupyter notebook full of backtested equity curves, a disclaimer about paper money, and silence about what happens when you actually try to run the thing continuously on real market data. Deployment is the gap. This post closes it — or at least closes enough of it to get a paper-trading bot running reliably on a homelab server, staying up through weekends, surviving restarts, and alerting you when something goes wrong. The technology stack is deliberately modest: Python, SQLite or Postgres, Docker Compose, and Alpaca&amp;rsquo;s free paper trading API. Nothing here requires a brokerage account, a Bloomberg terminal, or a co-location rack.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Error-Correcting Codes: From Hamming to Reed-Solomon</title>
      <link>/posts/error-correcting-codes-hamming-reed-solomon/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/error-correcting-codes-hamming-reed-solomon/</guid>
      <description>&lt;p&gt;Noise is the default condition of the universe, and reliable data storage and transmission are the exceptions that require engineering effort to achieve. Every bit you store on DRAM is sitting in a capacitor that leaks charge and can be flipped by a cosmic ray. Every byte you transmit over Wi-Fi passes through a channel that adds thermal noise, multipath interference, and occasional burst errors. The engineers who built the systems you depend on solved this problem with a branch of mathematics called coding theory — the study of how to add structured redundancy to data so that errors can be detected and corrected without retransmission or data loss.&lt;/p&gt;</description>
    </item>
    <item>
      <title>EtherChannel and Link Aggregation: LACP, PAgP, and When STP Blocks Half Your Bandwidth</title>
      <link>/posts/etherchannel-lacp-pagp-link-aggregation/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/etherchannel-lacp-pagp-link-aggregation/</guid>
      <description>&lt;p&gt;Spanning Tree Protocol is good at exactly one thing: preventing Layer 2 loops. What it is not good at is letting you use every link you paid for. In a standard redundant topology with two uplinks between an access switch and a distribution switch, STP will block one of them. The blocked link sits idle, providing failover protection but contributing zero bandwidth until its partner fails. For an access switch with a single 1 Gbps uplink, this means your maximum throughput is capped at 1 Gbps regardless of how many physical cables you run. Add a second cable and you still get 1 Gbps — the second link is blocked. Add a third and you still get 1 Gbps. STP is the answer to the loop problem but it introduces a bandwidth ceiling that feels arbitrary once you understand what is happening.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fiber Optics: From Total Internal Reflection to DWDM</title>
      <link>/posts/fiber-optics-total-internal-reflection-to-dwdm/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fiber-optics-total-internal-reflection-to-dwdm/</guid>
      <description>&lt;p&gt;Glass carries the internet because of an accident of physics: silica fiber is transparent enough, at the right wavelengths, that a signal can survive 80 kilometers before it needs amplification — and the amplifier that does the job runs on a rare-earth element whose energy levels happen to fall exactly where you need them. That chain of coincidences, from Snell&amp;rsquo;s Law through erbium to dense wavelength-division multiplexing, is what this post is about. Understanding it turns fiber optics from a black box of &amp;ldquo;light in a wire&amp;rdquo; into a system where every design choice — core diameter, wavelength, dispersion compensation, transceiver type — follows from first principles. It also makes the practical choices in a homelab or datacenter legible: why you cannot mix single-mode and multi-mode hardware, why 1550 nm rules long-haul, why hollow-core fiber threatens to rewrite the latency table.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How a Transistor Actually Works: From Sand to Switch</title>
      <link>/posts/how-a-transistor-actually-works/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-a-transistor-actually-works/</guid>
      <description>&lt;p&gt;Every line of software you have ever written runs because a voltage on a thin sliver of silicon can coax a river of electrons into existence or snuff it out in picoseconds. The transistor is not a curiosity of hardware engineers; it is the physical substrate of every abstraction in computing, from logical AND to a large language model. Understanding how it works — really works, not &amp;ldquo;it&amp;rsquo;s like a switch&amp;rdquo; — removes the magic from things that otherwise feel arbitrary: why smaller is faster, why smaller also leaks, why CMOS came to dominate, why fabs are now building structures smaller than a flu virus. The history starts with semiconductor physics, not with silicon specifically, and that distinction matters.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Chips Are Actually Fabbed: From Ingot to Package</title>
      <link>/posts/how-chips-are-actually-fabbed/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-chips-are-actually-fabbed/</guid>
      <description>&lt;p&gt;Every transistor you have ever used began as a lump of ordinary sand. The path from that sand — silicon dioxide, SiO2, the mineral quartz — to a finished chip running at five gigahertz involves crystal growth at 1,420 degrees Celsius, plasma torches bombarding wafers with ions at tens of thousands of electron-volts, mirrors polished to angstrom-level smoothness to focus light generated by exploding droplets of liquid tin, and roughly five hundred individual process steps executed in sequence without a single irrecoverable error. A modern logic fab is operating simultaneously at the scale of a beachball (the 300 mm wafer) and the scale of a water molecule (a 2 nm gate dielectric). That span of twelve orders of magnitude is the central engineering challenge, and it is why a leading-edge fabrication plant costs north of $20 billion to build before a single wafer has been processed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Data Lives on Platters and Flash: The Physics of Storage</title>
      <link>/posts/how-data-lives-on-platters-and-flash/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-data-lives-on-platters-and-flash/</guid>
      <description>&lt;p&gt;Every storage decision you make — which drives to buy, whether to trust SMR for a ZFS pool, how long an unpowered SSD retains data, why TLC endurance is a real concern in a write-heavy workload — traces back to physics happening at scales measured in nanometers. Most operators treat drives as black boxes and make reasonable choices by reading forum consensus. That works until it does not: until the SMR NAS drive stalls for three minutes under a ZFS scrub, or the TLC SSD in a build server loses data after six months unpowered in a drawer, or a QLC array fails sooner than the warranty implied it should. The physics underneath these failure modes is not complicated. It is, in fact, exactly the kind of thing that makes the abstractions click.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Monte Carlo Methods: Simulating Your Way Out of Hard Math</title>
      <link>/posts/monte-carlo-methods-simulation/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/monte-carlo-methods-simulation/</guid>
      <description>&lt;p&gt;The deepest problems in engineering and quantitative finance share an uncomfortable property: the exact answer is either analytically intractable or so expensive to derive that approximation is the only viable path. Monte Carlo methods are the systematic answer to this class of problem. Rather than attacking an integral analytically, you estimate it by drawing random samples from the relevant distribution and averaging the result. The approximation converges predictably, the error is quantifiable, and the approach generalizes to virtually any quantity that can be expressed as an expectation. Understanding how and why Monte Carlo works — and precisely when to reach for a different tool — is essential for anyone building systems that reason under uncertainty.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Portfolio Optimization in Python: Mean-Variance, Risk Parity, and the Covariance Problem</title>
      <link>/posts/portfolio-optimization-python/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/portfolio-optimization-python/</guid>
      <description>&lt;p&gt;Modern portfolio theory is one of the most cited ideas in finance and one of the most quietly abandoned in practice. The Markowitz mean-variance framework earned a Nobel Prize in 1990 for formalizing something intuitively obvious — diversification reduces risk — and spent the next three decades getting humbled by the gap between theory and the actual behavior of financial data. The framework is not wrong, exactly. It is sensitive: sensitive to input estimates, sensitive to the length of the lookback window, sensitive to whether your covariance matrix is well-conditioned. Feed it slightly wrong expected returns and it produces portfolios that are extreme, concentrated, and unstable across rebalancing periods. The optimizer does not know it is working with estimates. It treats your sample statistics as ground truth and finds the mathematically correct answer to a question you asked incorrectly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Queueing Theory for Capacity Planning: Why Latency Explodes at 80%</title>
      <link>/posts/queueing-theory-capacity-planning/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/queueing-theory-capacity-planning/</guid>
      <description>&lt;p&gt;Every experienced engineer has seen the pattern: a service runs at 60% CPU and responds in 5 ms, load climbs to 80% and latency creeps to 20 ms, the team adds one more batch job and suddenly p99 is measured in seconds. The on-call engineer scales up, latency drops, and everyone agrees to &amp;ldquo;watch utilization more closely.&amp;rdquo; What almost no one does is explain &lt;em&gt;why&lt;/em&gt; the degradation happened so suddenly, or derive a principled threshold that could have prevented the incident in the first place.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Risk Metrics for Engineers: VaR, Sharpe, Sortino, and Max Drawdown</title>
      <link>/posts/risk-metrics-var-sharpe-sortino/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/risk-metrics-var-sharpe-sortino/</guid>
      <description>&lt;p&gt;Every portfolio risk metric is a compression artifact. You take a high-dimensional, path-dependent, fat-tailed process — the actual behavior of a portfolio over time — and you squeeze it into a single number. That number is useful precisely because it throws away most of the information. The danger is forgetting what got thrown away.&lt;/p&gt;&#xA;&lt;p&gt;Sharpe, Sortino, VaR, CVaR, and maximum drawdown are the standard vocabulary of quantitative risk management. They appear in every fund pitch deck, every backtesting report, every regulatory filing. Engineers building trading systems or risk dashboards need to understand not just the formulas but the failure modes — the regimes in which a metric looks fine while the portfolio quietly loads a gun. This guide covers the math, the pandas implementation, and the honest critique.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Shannon and Information Theory: The 1948 Paper That Named the Bit</title>
      <link>/posts/shannon-information-theory/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/shannon-information-theory/</guid>
      <description>&lt;p&gt;In July 1948, a 32-year-old mathematician at Bell Telephone Laboratories published a two-part paper in the Bell System Technical Journal titled &amp;ldquo;A Mathematical Theory of Communication.&amp;rdquo; It was not a hardware design. It was not an algorithm. It was a precise answer to a question that nobody had managed to ask cleanly before: what &lt;em&gt;is&lt;/em&gt; information, and how much of it can you reliably move through a physical channel? The paper introduced the word &lt;strong&gt;bit&lt;/strong&gt;, gave a formula for entropy that would reappear in thermodynamics, machine learning, gambling theory, and compression algorithms, and drew hard limits — limits that no engineering cleverness can breach — around what every communications system you have ever used can do. We are still building inside those limits.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Signal Integrity: Why Your Cat6 Cable Is Twisted</title>
      <link>/posts/signal-integrity-why-cat6-is-twisted/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/signal-integrity-why-cat6-is-twisted/</guid>
      <description>&lt;p&gt;Every network engineer has done it: pulled a cable, terminated a keystone, tested continuity, and watched the switch port refuse to negotiate above 100 Mbit/s. The usual diagnosis is &amp;ldquo;bad cable&amp;rdquo; or &amp;ldquo;too long.&amp;rdquo; Those are correct, but they are not explanations. The real explanation runs through transmission-line theory, differential signaling, electromagnetic crosstalk, and the skin effect — physics that was worked out between roughly 1850 and 1910, applied to copper foil and PVC jackets in your patch closet right now. Understanding it does not change how you pull cable, but it changes what you look for when something goes wrong, and it is a prerequisite for understanding why Cat6a is physically different from Cat6 in ways that matter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Solder Metallurgy: Eutectics, Whiskers, and Why Lead-Free Is Harder</title>
      <link>/posts/solder-metallurgy-eutectic-whiskers-lead-free/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/solder-metallurgy-eutectic-whiskers-lead-free/</guid>
      <description>&lt;p&gt;The solder joint is one of the most unglamorous objects in electronics, and one of the most consequential. Billions are made every hour. Most will outlast the device they live in. A meaningful fraction will not — and when they fail, they tend to do so in ways that are maddeningly hard to reproduce: intermittent opens under vibration, subtle shorts that only emerge months after manufacture, catastrophic dendrite growth that bridges conductors in sealed military hardware years after deployment. The engineering of the solder joint is not a matter of melting metal and letting it cool. It is a materials science problem involving phase diagrams, intermetallic compound kinetics, flux chemistry, and the thermodynamics of solidification — and the industry&amp;rsquo;s forced march away from lead-bearing alloys since RoHS took effect in 2006 has made every one of those problems harder without making any of them easier.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Fourier Transform, Finally Intuitive</title>
      <link>/posts/fourier-transform-intuitive/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fourier-transform-intuitive/</guid>
      <description>&lt;p&gt;The Fourier transform is the mathematical bedrock underneath more of the modern world than most engineers realize. Your MP3 file, the Wi-Fi packet reaching your laptop, the spectrum analyzer display on an oscilloscope, the JPEG sitting in your browser, the 5G subcarrier slicing the airwaves outside your window — every one of them rests on a single idea, stated by Joseph Fourier in 1822 and refined into a fast algorithm by Cooley and Tukey in 1965: &lt;strong&gt;any signal can be decomposed into a sum of sinusoids of different frequencies, amplitudes, and phases.&lt;/strong&gt; Everything else is engineering built on that foundation. This post works through the insight carefully — no LaTeX, math in code blocks — then follows it through the DFT, the FFT butterfly, windowing, real applications, and practical Python you can run today.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Kelly Criterion: Position Sizing as an Engineering Problem</title>
      <link>/posts/kelly-criterion-position-sizing/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kelly-criterion-position-sizing/</guid>
      <description>&lt;p&gt;Position sizing is the part of trading and bankroll management that textbooks treat as an afterthought. Pick a strategy, test it, then bet &amp;ldquo;some reasonable fraction&amp;rdquo; of your capital. That afterthought will determine whether a profitable strategy makes you wealthy or blows you up — often more than edge quality does. The Kelly Criterion is the rigorous answer to the question of how much to bet, derived not from finance theory but from Claude Shannon&amp;rsquo;s Bell Labs work on information and entropy. Getting it right requires understanding where it comes from, what it assumes, and precisely how wrong your inputs can be before it turns on you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Polymer Science of 3D Printing Filament</title>
      <link>/posts/polymer-science-3d-printing-filament/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/polymer-science-3d-printing-filament/</guid>
      <description>&lt;p&gt;The failure modes of 3D printing filament are not arbitrary. A PLA bracket that slowly bends under a cable harness, a PETG part that weeps fine threads between features, an ABS enclosure panel that peels off the bed and curls at its corners — each of these is a specific, predictable consequence of the polymer&amp;rsquo;s molecular architecture interacting with heat, stress, and time. Understanding those mechanisms does not just explain why prints fail; it tells you exactly which material to choose for a given application, which settings actually matter and which are cargo-cult superstition, and how far you can push a part before chemistry overrules optimism.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Thermodynamics of Cooling Your Rack</title>
      <link>/posts/thermodynamics-of-cooling-your-rack/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/thermodynamics-of-cooling-your-rack/</guid>
      <description>&lt;p&gt;The first law of thermodynamics, applied to your rack: every watt your equipment consumes is converted to heat with an efficiency that asymptotically approaches 100%. There are no partial conversions to useful mechanical work, no radiated photons carrying away meaningful energy, no chemical potential storage. The CPU does computation; the memory does addressing; the drives do seeking — and then every joule spent on all of it exits as thermal energy into the air around your machines. Your homelab is not a computer that happens to produce heat as a side effect. It is a resistive heater that happens to run Linux.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Thermal Paste and Interface Materials: What Is Actually in the Tube</title>
      <link>/posts/thermal-paste-interface-materials/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/thermal-paste-interface-materials/</guid>
      <description>&lt;p&gt;Every cooler review benchmarks thermal paste as if the difference between brands were the deciding variable, but almost none of them explain what the material is actually doing or why it works. The thermal interface material (TIM) sitting between a CPU die or integrated heat spreader and a cooler&amp;rsquo;s contact plate is doing something surprisingly subtle: it is not conducting heat better than copper, it is eliminating the air that would otherwise fill the microscopic voids between two surfaces that look flat but are not. Understanding that distinction — and understanding the chemistry that makes different materials better or worse at filling those voids — changes how you think about every thermal compound decision from a desktop repaste to a server maintenance schedule.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why GPS Needs General Relativity</title>
      <link>/posts/why-gps-needs-general-relativity/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/why-gps-needs-general-relativity/</guid>
      <description>&lt;p&gt;Every time a navigation app pins your location to the correct side of a street, it is silently depending on two of the most counterintuitive results in the history of physics. The GPS satellites overhead are not simply bouncing signals back like radio rangefinders. They are flying clocks, and the accuracy of your position is a direct function of how accurately those clocks agree with each other and with clocks on the ground. Keeping that agreement requires accounting for the fact that time does not pass at the same rate at 20,200 kilometers altitude as it does at sea level — a consequence of Einstein&amp;rsquo;s general theory of relativity — and for the fact that a clock moving at orbital velocity ticks more slowly than a stationary one, a consequence of special relativity. Both effects are real, both are measurable, and together they shift GPS clock rates by 38 microseconds per day. Left uncorrected, that drift accumulates into roughly 10 kilometers of position error every 24 hours.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Yxk Zero1 4-Bay NAS: OS Options, Use Cases, and Drive Recommendations</title>
      <link>/posts/yxk-zero1-nas-guide/</link>
      <pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/yxk-zero1-nas-guide/</guid>
      <description>&lt;p&gt;The homelab NAS market has quietly gotten interesting at the low end. Devices like the Yxk Zero1 land somewhere between a consumer plug-and-play box (think Synology DS423+) and a full DIY build, offering a real x86 platform with an Intel N100, dual 2.5 Gigabit Ethernet, and 8 GB of RAM in a diskless desktop chassis — all for roughly $170–$200 before drives. That combination unlocks options that ARM-based consumer NAS units simply cannot match: you can install TrueNAS SCALE, Proxmox VE, Unraid, OpenMediaVault, or plain Debian, and the OS will behave exactly as documented because you are running on generic x86_64 hardware with a real UEFI BIOS. The Zero1 is also marketed under the Iron Cow brand (Iron Cow NAS-ZERO 1 / Zero1 Pro), and community members on the TrueNAS forums have confirmed that TrueNAS SCALE 25.10 installs and runs without unusual friction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bell Labs and the Transistor: The Lab That Built the Modern World</title>
      <link>/posts/bell-labs-and-the-transistor/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bell-labs-and-the-transistor/</guid>
      <description>&lt;p&gt;Every device you own descends from a slab of germanium on a lab bench in Murray Hill, New Jersey, on December 16, 1947. That is not rhetorical flourish; it is a literal supply chain. The point-contact transistor begat the junction transistor, which begat the silicon transistor, which begat the planar process, which begat the integrated circuit, which begat everything with a power button. And the institution that produced it — Bell Telephone Laboratories — also produced information theory, the solar cell, the laser&amp;rsquo;s theoretical foundation, the CCD, UNIX, the C programming language, and the accidental discovery of the Big Bang&amp;rsquo;s afterglow. Eleven Nobel Prizes and five Turing Awards trace to work done at one industrial lab.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: First Hop Redundancy Protocols — HSRP, VRRP, and GLBP</title>
      <link>/posts/ccna-fhrp-hsrp-first-hop-redundancy/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-fhrp-hsrp-first-hop-redundancy/</guid>
      <description>&lt;p&gt;Every host on a subnet is configured with exactly one default gateway. It is a single IP address — &lt;code&gt;192.168.1.1&lt;/code&gt;, say — and every packet bound for another network is handed to it. That gateway is also, by default, a single point of failure. If the router holding &lt;code&gt;192.168.1.1&lt;/code&gt; reboots, loses power, or has its uplink cut, every host on that subnet is stranded: they keep ARPing for a gateway that no longer answers, and there is no mechanism in IPv4 for a host to notice and fail over on its own. You can put two routers on the subnet, but a host only knows one gateway address, so the second router sits idle and useless. &lt;strong&gt;First Hop Redundancy Protocols (FHRPs)&lt;/strong&gt; solve exactly this: they let two or more physical routers share a single &lt;em&gt;virtual&lt;/em&gt; IP and virtual MAC address, present it to hosts as &amp;ldquo;the gateway,&amp;rdquo; and silently elect which physical router actually forwards for it — failing over in seconds when that router dies, with the hosts none the wiser. This is CCNA 200-301 topic 3.5, and the three protocols you need to know are &lt;strong&gt;HSRP&lt;/strong&gt;, &lt;strong&gt;VRRP&lt;/strong&gt;, and &lt;strong&gt;GLBP&lt;/strong&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Claude Fable 5 vs Opus: A Realistic Look at Whether You Need the Mythos-Class Model</title>
      <link>/posts/claude-fable-5-vs-opus-realistic-comparison/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/claude-fable-5-vs-opus-realistic-comparison/</guid>
      <description>&lt;p&gt;Anthropic released Claude Fable 5 today — June 9, 2026 — and the marketing is doing what launch-day marketing always does: every benchmark chart points up and to the right, every quote is from a customer who swears the extra cost pays for itself. The actual question for most of us is more boring and more important: Fable 5 costs &lt;strong&gt;double&lt;/strong&gt; what Opus 4.8 costs, so will you personally notice the difference, or are you about to pay a 2x premium for answers that Sonnet 4.6 would have given you at a sixth of the price?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Decoding Market Indicators with Code: OBV and the Golden Cross from Scratch</title>
      <link>/posts/decoding-market-indicators-with-code/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/decoding-market-indicators-with-code/</guid>
      <description>&lt;p&gt;To an engineer, a stock chart covered in moving averages and oscillators can look like astrology with extra steps — a pile of lines whose names (&amp;ldquo;On-Balance Volume,&amp;rdquo; &amp;ldquo;Golden Cross,&amp;rdquo; &amp;ldquo;Stochastic RSI&amp;rdquo;) suggest more meaning than math. But every technical indicator is, underneath, a small and completely deterministic function over a time series of price and volume. There is no magic: given the same input bars, an indicator produces the same output, every time, and you can write it in a dozen lines of Python. Understanding indicators &lt;em&gt;as code&lt;/em&gt; does two things at once. It strips away the mystique — you see exactly what is being computed and therefore exactly what it can and cannot tell you — and it exposes the real traps, which are almost never in the formula and almost always in how you wire the data up (look-ahead bias, off-by-one signal timing, survivorship in your backtest). This post implements two canonical indicators from scratch: &lt;strong&gt;On-Balance Volume (OBV)&lt;/strong&gt;, a running sum that uses volume to confirm price, and the &lt;strong&gt;Golden Cross&lt;/strong&gt;, a moving-average crossover you can detect precisely. We will write them vectorized in pandas, interpret them honestly, and be clear-eyed about what a lagging indicator actually is: a compressed description of the past, not a forecast of the future.&lt;/p&gt;</description>
    </item>
    <item>
      <title>From ARPANET to BGP: Why the Internet Trusts Everyone</title>
      <link>/posts/arpanet-to-bgp-internet-trust/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/arpanet-to-bgp-internet-trust/</guid>
      <description>&lt;p&gt;Every time you load a web page, your packets are guided across the planet by a protocol that, at its core, believes whatever it is told. Any of the roughly 80,000 autonomous systems that make up the internet can announce &amp;ldquo;I am the best path to this address space,&amp;rdquo; and by default, the rest of the world simply accepts it. This is not an oversight that slipped past review. It is the fossilized imprint of a design decision made for a network of a few dozen universities and research labs, where every operator knew every other operator by name, and the worst plausible failure was a bug, not a lie.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Cell Networks Actually Work: 1G to 5G</title>
      <link>/posts/how-cell-networks-work-1g-to-5g/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-cell-networks-work-1g-to-5g/</guid>
      <description>&lt;p&gt;The cellular network is the largest machine most people touch every day, and almost nobody who works in tech can explain how it works. Network engineers who can recite the TCP state machine from memory will wave vaguely at &amp;ldquo;the towers&amp;rdquo; when asked how a phone call survives a drive down the interstate. That&amp;rsquo;s a shame, because the cellular system is one of the great engineering stories: a 1947 Bell Labs memo that sat on a shelf for thirty years, a standards war between Europe and a San Diego startup, a text-messaging feature smuggled in through a signaling channel, and a physics problem — spectrum is finite — that every generation has attacked with a different weapon.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How the Power Grid Works: An Engineer&#39;s Tour of the Largest Machine Ever Built</title>
      <link>/posts/how-the-power-grid-works/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/how-the-power-grid-works/</guid>
      <description>&lt;p&gt;The North American power grid is routinely called the largest machine ever built, and the description is literal: hundreds of thousands of miles of transmission line, thousands of generating plants, and every motor, transformer, and phone charger east of the Rockies are physically coupled into a single electromechanical system, spinning in lockstep at 60 Hz. When you flip a switch in Cleveland, generators in Tennessee feel it within seconds. There is no other machine — not the internet, not the global shipping fleet — whose components are this tightly synchronized across a continent.&lt;/p&gt;</description>
    </item>
    <item>
      <title>k3s vs k8s: Lightweight Kubernetes or the Full Thing?</title>
      <link>/posts/k3s-vs-k8s-lightweight-vs-full-kubernetes/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/k3s-vs-k8s-lightweight-vs-full-kubernetes/</guid>
      <description>&lt;p&gt;The phrase &amp;ldquo;k3s vs k8s&amp;rdquo; sets up a comparison that is mostly a misunderstanding. People hear &amp;ldquo;k3s&amp;rdquo; and assume it is a lighter, lossy imitation of &amp;ldquo;real&amp;rdquo; Kubernetes — a different thing you settle for when you can&amp;rsquo;t run the full article. It is not. &lt;strong&gt;k3s is a CNCF-certified, fully conformant Kubernetes distribution.&lt;/strong&gt; It passes the same conformance test suite as upstream Kubernetes, exposes the same API, and runs your Deployments, Services, Ingresses, and Helm charts without a single change. What k3s changes is &lt;em&gt;packaging and operations&lt;/em&gt;, not the Kubernetes API: it collapses the control plane into one small binary, swaps a few default components for lighter equivalents, makes etcd optional, and bundles &amp;ldquo;batteries&amp;rdquo; so a working cluster comes up from a single command. So the honest framing is not &amp;ldquo;the lite version vs the real version&amp;rdquo; — it is &amp;ldquo;the same Kubernetes, packaged for a small footprint and easy operation, vs the same Kubernetes assembled the upstream way.&amp;rdquo; The right choice depends entirely on &lt;em&gt;who operates it, on what hardware, at what scale&lt;/em&gt; — not on what features you&amp;rsquo;ll lose, because you lose almost none. This post explains exactly what k3s does differently, where that helps, and where its conveniences can bite. If you are new to the underlying concepts, start with the &lt;a href=&#34;/posts/kubernetes-basics/&#34;&gt;Kubernetes basics primer&lt;/a&gt; and come back.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Measuring What Your Homelab Actually Costs</title>
      <link>/posts/measuring-homelab-power-costs/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/measuring-homelab-power-costs/</guid>
      <description>&lt;p&gt;Ask a homelabber what their rack costs to run and you will usually get one of two answers: a shrug, or a number derived from PSU nameplates that is wrong by a factor of five to ten. Both answers are a problem. The shrug means you cannot make rational decisions about consolidating hosts, retiring that dual-Xeon space heater, or whether self-hosted storage actually beats Backblaze. The nameplate number means you have probably talked yourself out of hardware that would have been fine, or you are carrying a vague guilt about a lab that actually costs less than two streaming subscriptions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Network Address Translation (NAT): A CCNA-Focused Guide</title>
      <link>/posts/nat-network-address-translation-ccna/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nat-network-address-translation-ccna/</guid>
      <description>&lt;p&gt;Network Address Translation is the duct tape that has held IPv4 together for thirty years: it lets a whole network of private addresses share a handful of public ones, and it is the reason your home of twenty devices reaches the internet through a single ISP-assigned address. For the CCNA it is not optional trivia — exam topic 4.6 explicitly requires you to &lt;strong&gt;configure and verify inside source NAT using static and pools&lt;/strong&gt;, which means CLI fluency in static NAT, dynamic NAT, and PAT, plus the ability to label the four NAT address types and explain what NAT does to a packet. The concept is simple, the terminology is where people lose marks, and the configuration has exactly one gotcha that breaks everyone&amp;rsquo;s first attempt. This guide covers all three in the order the exam tests them, with config you can lab, then steps back to NAT&amp;rsquo;s real role and its honest downsides. It pairs naturally with the &lt;a href=&#34;/posts/ipam-ip-address-management-ccna/&#34;&gt;CCNA IPAM guide&lt;/a&gt;, which covers the private address space NAT exists to translate.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Outlets and PoE Drops: Where to Put Power and Network Before the Drywall Goes Up</title>
      <link>/posts/outlet-placement-and-poe-drop-planning-guide/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/outlet-placement-and-poe-drop-planning-guide/</guid>
      <description>&lt;p&gt;There is a moment in every build or remodel when the walls are open, the studs are bare, and adding an outlet or a network drop costs about fifteen minutes and a few dollars of wire. Then the drywall goes up, and the same outlet becomes a half-day of cutting, fishing, patching, and painting — if it&amp;rsquo;s reachable at all. The difference between a house that works and a house full of extension cords and Wi-Fi dead zones is almost entirely decided in that window, which is why outlet and drop placement deserves an actual plan rather than &amp;ldquo;wherever the electrician defaults to.&amp;rdquo; The plan has two halves that people consistently get wrong in opposite ways: &lt;strong&gt;line-voltage outlets&lt;/strong&gt;, where the electrical code dictates a minimum that most people mistake for a design (it isn&amp;rsquo;t — it&amp;rsquo;s a floor), and &lt;strong&gt;low-voltage PoE drops&lt;/strong&gt;, where there is no code minimum at all, so most houses get zero and their owners spend years compensating with Wi-Fi cameras on batteries and access points balanced on bookshelves. This guide walks both: the code rules you build on, the rooms where the minimum fails you, the odd-but-brilliant outlet locations like a &lt;strong&gt;switched soffit outlet under your roofline&lt;/strong&gt;, and a complete map of where PoE drops earn their keep — cameras, doorbells, access points, and the gear you haven&amp;rsquo;t bought yet. It is the companion to the &lt;a href=&#34;/posts/home-remodel-network-wiring-guide/&#34;&gt;home remodel network wiring guide&lt;/a&gt;, which covers the cable, conduit, and panel side in depth.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Raspberry Pi vs the Competition: How the SBC Landscape Stacks Up in 2026</title>
      <link>/posts/raspberry-pi-vs-competitors-sbc-comparison/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/raspberry-pi-vs-competitors-sbc-comparison/</guid>
      <description>&lt;p&gt;Ask which single-board computer to buy and the reflexive answer is &amp;ldquo;a Raspberry Pi&amp;rdquo; — but the reflex hides an uncomfortable truth: in raw 2026 hardware terms, the Pi is no longer the leader. A Rockchip RK3588 board from Orange Pi or Radxa gives you eight CPU cores to the Pi 5&amp;rsquo;s four, an onboard NVMe slot and dual 2.5-gigabit Ethernet the Pi needs add-on HATs to match, and a built-in NPU — frequently for &lt;em&gt;less&lt;/em&gt; money. On a spec sheet, the Pi loses. And yet it remains the right choice for most people most of the time, because the thing you are actually buying with a Raspberry Pi is not the silicon. It is the &lt;strong&gt;software, the ecosystem, and the supply chain&lt;/strong&gt;: an operating system built specifically for the board, thousands of HATs and cameras that just work, documentation and a community so deep that any problem you hit has been solved and written up, and a manufacturer that commits to producing the board for years rather than vanishing after one production run. The competitors win benchmarks; the Pi wins the part that comes &lt;em&gt;after&lt;/em&gt; you plug it in. This guide takes the whole field seriously — the RK3588 challengers, the proven-stable Odroid, NVIDIA&amp;rsquo;s AI-focused Jetson, the x86 mini-PC alternative, and the microcontroller floor below all of them — and gives you a framework for choosing the board that fits the job rather than the one with the best headline numbers. For where these boards fit in a broader homelab build, pair this with the &lt;a href=&#34;/posts/homelab-hardware-guide/&#34;&gt;homelab hardware guide&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RISC vs CISC: The War That Ended in a Tie</title>
      <link>/posts/risc-vs-cisc-war-ended-in-a-tie/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/risc-vs-cisc-war-ended-in-a-tie/</guid>
      <description>&lt;p&gt;For about fifteen years, computer architecture had a genuine ideological war. On one side: complex instruction set computers, machines whose instructions read like a high-level language, championed by DEC&amp;rsquo;s VAX and defended by everyone with a software ecosystem to protect. On the other: a band of academic insurgents from IBM Research, Berkeley, and Stanford who argued that all of that complexity was not just unnecessary but actively harmful, and that a brutally simple machine, designed around what compilers actually emit, would be faster, cheaper, and easier to build. The insurgents were right about almost everything. They published the measurements, built the prototypes, founded the companies, and by 1992 owned every performance crown that mattered.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SCADA and Industrial Control Systems: A Defensive Tour</title>
      <link>/posts/scada-industrial-control-systems-defensive-tour/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/scada-industrial-control-systems-defensive-tour/</guid>
      <description>&lt;p&gt;Somewhere within a few kilometers of you, right now, a programmable logic controller is reading a sensor, comparing the value to a setpoint, and deciding whether to open a valve. It has been doing this every few milliseconds for years, possibly decades. It runs your water pressure, your electricity, the traffic lights on your commute, and the production line that made your coffee mug. It probably speaks a protocol designed in 1979 with no concept of authentication, and it cannot be rebooted without someone filing paperwork, because rebooting it stops a physical process that people depend on.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Solar and Battery Backup for Network Gear: A Reality Check</title>
      <link>/posts/solar-battery-backup-for-network-gear/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/solar-battery-backup-for-network-gear/</guid>
      <description>&lt;p&gt;Every few months someone in a homelab forum posts a photo of a rack, a solar panel, and a battery, captioned &amp;ldquo;going off-grid with my network.&amp;rdquo; It is a seductive idea: free electrons, silent backup power, independence from the utility. And the hardware to do it has never been cheaper — LiFePO4 batteries are under $250/kWh for finished packs, bare panels are under a dollar a watt, and a Victron MPPT controller costs less than a mid-range PoE switch. The pieces are affordable, well documented, and genuinely fun to build with.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Apollo Guidance Computer: 2K of RAM to the Moon</title>
      <link>/posts/apollo-guidance-computer/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apollo-guidance-computer/</guid>
      <description>&lt;p&gt;In July 1969, a computer with less working memory than a single modern emoji burst guided two humans onto the surface of the Moon, and it did so while throwing error codes. Five program alarms fired in the final four minutes of the Apollo 11 descent — alarms nobody in the cockpit fully understood, on a machine running at 100% capacity plus roughly 13% of phantom load it never should have had — and the landing continued anyway, because the software was designed on the assumption that it would someday be asked to do more than it could, and that the correct response to overload was not to crash but to decide what mattered.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Capacitor Plague: How Stolen Electrolyte Killed a Decade of Hardware</title>
      <link>/posts/the-capacitor-plague/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-capacitor-plague/</guid>
      <description>&lt;p&gt;Sometime around 2003, a measurable fraction of the world&amp;rsquo;s personal computers began dying of the same disease. The symptom was visible to the naked eye: small aluminum cylinders on the motherboard, normally flat-topped, swelling into little domes, splitting along their scored vents, and weeping brown crust onto the PCB. Machines that had worked perfectly for eighteen months started failing to POST, rebooting under load, corrupting memory. The cause traced back to a single act of industrial espionage gone wrong — a stolen electrolyte formula that was stolen &lt;em&gt;incompletely&lt;/em&gt;, missing the additives that kept the chemistry from slowly manufacturing hydrogen gas inside a sealed can. The trade press called it the capacitor plague, and before it burned out it had touched Abit, Dell, Apple, HP, IBM, and Intel, cost Dell alone on the order of $420 million, and put the phrase &amp;ldquo;bulging caps&amp;rdquo; permanently into the vocabulary of anyone who fixes computers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Complete CCNA 200-301 Study Guide: Every Topic, Linked</title>
      <link>/posts/ccna-200-301-complete-study-guide/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-200-301-complete-study-guide/</guid>
      <description>&lt;p&gt;The CCNA is Cisco&amp;rsquo;s associate-level certification and the single most recognized entry credential in networking. The current exam, &lt;strong&gt;200-301 CCNA v1.1&lt;/strong&gt; (refreshed August 2024), is one 120-minute test covering six domains, from how a frame crosses a switch to how you automate a network with Python and REST APIs. The blueprint is broad but shallow — it rewards understanding the &lt;em&gt;why&lt;/em&gt; of each technology far more than memorizing command syntax — and the hardest part for most candidates is simply seeing the whole thing at once and knowing which topics they have actually internalized versus merely read. This post is that map. Every exam domain below lists its topics, each linked to a full deep-dive post on this blog, so you can navigate the entire CCNA body of knowledge from one page. Where a topic is still being written, it is marked as such rather than linked. Treat this as the index; treat each linked post as the chapter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Engineering of Options Trading: The Greeks as Partial Derivatives</title>
      <link>/posts/engineering-of-options-trading-the-greeks/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/engineering-of-options-trading-the-greeks/</guid>
      <description>&lt;p&gt;Options intimidate people because the vocabulary sounds like a trading-floor secret handshake — &amp;ldquo;I&amp;rsquo;m long gamma, short vega, and my theta is bleeding.&amp;rdquo; But to an engineer, an option is just a &lt;strong&gt;function&lt;/strong&gt;: its value &lt;code&gt;V&lt;/code&gt; depends on a handful of state variables — the underlying price &lt;code&gt;S&lt;/code&gt;, time &lt;code&gt;t&lt;/code&gt;, volatility &lt;code&gt;σ&lt;/code&gt;, the risk-free rate &lt;code&gt;r&lt;/code&gt;, and the fixed contract terms (strike &lt;code&gt;K&lt;/code&gt;, expiry &lt;code&gt;T&lt;/code&gt;). And once you have a function of several variables, the natural thing to ask is &lt;em&gt;how sensitive is the output to each input?&lt;/em&gt; That question has a name in calculus — the partial derivative — and in options it has a name in Greek letters. &lt;strong&gt;The Greeks are nothing more than the partial derivatives of the pricing function.&lt;/strong&gt; Delta is ∂V/∂S, Gamma is the second derivative ∂²V/∂S², Theta is ∂V/∂t, Vega is ∂V/∂σ, Rho is ∂V/∂r. That is the whole conceptual payload. Everything else — delta-hedging, the gamma-theta tradeoff, &amp;ldquo;long vol&amp;rdquo; — is just risk management built on knowing those sensitivities and trying to control the ones you don&amp;rsquo;t want exposure to. This post treats the Greeks the way an engineer would treat any system: as a set of measurable sensitivities you compute, monitor, and hedge. We will price an option with Black-Scholes, derive its Greeks in closed form, implement them in Python, and then use them to manage risk the way a desk actually does.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Morris Worm: The Internet&#39;s First Incident Response</title>
      <link>/posts/morris-worm-incident-response/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/morris-worm-incident-response/</guid>
      <description>&lt;p&gt;On the evening of November 2, 1988, system administrators across the United States watched their VAX and Sun machines grind to a halt under mysterious load. Processes multiplied faster than they could be killed. Rebooting helped for minutes, then the load returned. By morning, an estimated 6,000 machines — something like 10% of the roughly 60,000 hosts on the internet at the time — were effectively offline. There was no CERT to call, no incident response playbook, no security mailing list that could reach anyone, because the network the mailing lists ran on was the thing that was down.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Undersea Cables: The Internet&#39;s Physical Layer</title>
      <link>/posts/undersea-cables-internet-physical-layer/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/undersea-cables-internet-physical-layer/</guid>
      <description>&lt;p&gt;Every diagram of the internet you have ever seen is a lie of abstraction. The cloud is not a cloud. When you open a video call from Denver to Frankfurt, your packets do not ascend to a satellite; they dive into the Atlantic inside a polyethylene tube about as thick as a garden hose, lying on the abyssal plain four kilometers down, and they do it because nothing else comes close on cost, capacity, or latency. Submarine fiber carries over 99% of intercontinental data traffic. The satellite constellations that dominate headlines carry a rounding error by comparison — Starlink&amp;rsquo;s entire system throughput is in the low hundreds of terabits per second globally, which is roughly what two modern cables deliver across a single ocean.&lt;/p&gt;</description>
    </item>
    <item>
      <title>UPS Sizing and NUT for the Homelab: Graceful Shutdown Done Right</title>
      <link>/posts/ups-sizing-and-nut-for-the-homelab/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ups-sizing-and-nut-for-the-homelab/</guid>
      <description>&lt;p&gt;A UPS in a homelab has one job, and it is not the job most people buy it for. It is not there to keep Plex running through a thunderstorm. It is there to buy your machines enough time to shut down cleanly — to let Proxmox drain its VMs, let TrueNAS flush its ZFS transaction groups, and let everything halt in the right order before the battery gives out. A ZFS pool will almost always survive a hard power cut, but &amp;ldquo;almost always&amp;rdquo; is a miserable phrase to bet a decade of family photos on, and the SQLite databases, container volumes, and half-written VM disks scattered across a typical homelab are far less forgiving than ZFS is.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Your Homelab Burns 300W Doing Nothing</title>
      <link>/posts/homelab-idle-power-optimization/</link>
      <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/homelab-idle-power-optimization/</guid>
      <description>&lt;p&gt;Plug a power meter into the wall feed of a typical homelab rack and you will see a number that does not move much: 280, 300, maybe 350 watts, around the clock, whether anyone is using anything or not. The services are idle. The VMs are idle. The disks are serving nobody. And yet the rack draws as much continuous power as four or five refrigerators. At 300W continuous, you are buying 2,628 kWh per year — roughly $394 at a cheap US rate of $0.15/kWh, and over $1,100 at German residential prices. That is real money spent on machines waiting for work that mostly never comes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IP Address Management (IPAM): A CCNA-Focused Guide</title>
      <link>/posts/ipam-ip-address-management-ccna/</link>
      <pubDate>Mon, 08 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ipam-ip-address-management-ccna/</guid>
      <description>&lt;p&gt;IP Address Management is the unglamorous discipline that keeps a network from collapsing into a pile of address conflicts: planning your address space, allocating subnets to sites and VLANs, tracking what is assigned to what, and reclaiming space when it&amp;rsquo;s freed. The CCNA exam never asks you to log into Infoblox or NetBox — but it tests, heavily, every single building block that IPAM is built from. The largest domain on the 200-301 blueprint, &lt;strong&gt;IP Connectivity at 25%&lt;/strong&gt;, is essentially &amp;ldquo;can you manage addresses,&amp;rdquo; and the IP Services domain layers DHCP and DNS on top. So the fastest way to both pass the exam &lt;em&gt;and&lt;/em&gt; understand what a senior network engineer actually does all day is to learn the fundamentals through the lens of how address space is really managed. That is what this guide does: it teaches subnetting, VLSM, DHCP, DNS, and IPv6 the way the exam expects, then shows how those concepts scale up into the tools that run them in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AV Receivers and Home Theater Speakers: A 2026 Buyer&#39;s Guide</title>
      <link>/posts/av-receivers-and-home-theater-speakers-guide/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/av-receivers-and-home-theater-speakers-guide/</guid>
      <description>&lt;p&gt;A home theater audio system is two purchases that have to agree with each other: the &lt;strong&gt;receiver&lt;/strong&gt; that decodes and powers everything, and the &lt;strong&gt;speakers&lt;/strong&gt; that turn that power into sound. People obsess over the speaker brand and underthink the receiver, or buy a flagship receiver and pair it with thin speakers that waste it. The truth is that the speakers determine the &lt;em&gt;character&lt;/em&gt; of the sound and the receiver determines whether the system is &lt;em&gt;capable&lt;/em&gt; of the formats and channel counts you want — and that the single most impactful component, dollar for dollar, is usually the &lt;strong&gt;subwoofer&lt;/strong&gt;, which most beginners skimp on. This guide covers the receiver first (because it sets the ceiling on what your system can ever do), then the speakers, then how to split a budget across them sensibly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Grills Compared: Pellet vs Gas vs Charcoal vs Kamado</title>
      <link>/posts/grill-types-compared-pellet-gas-charcoal-kamado/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grill-types-compared-pellet-gas-charcoal-kamado/</guid>
      <description>&lt;p&gt;There is no best grill, only the best grill for how you cook and how patient you are. The four mainstream types — gas, charcoal, pellet, and kamado — sit on a spectrum from &amp;ldquo;convenience&amp;rdquo; to &amp;ldquo;flavor and control,&amp;rdquo; and almost every disagreement at the hardware store is really a disagreement about where on that spectrum you want to live. A gas grill is a kitchen appliance that lives outside: fast, predictable, low-drama. A kamado is a craft tool: extraordinary results, but it asks something of you. Pellet grills tried to split the difference and mostly succeeded, which is why they have taken over so many backyards. This guide explains the real trade-offs so you buy the one you will actually use.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Microsoft Scout: When OpenClaw Grew a Suit and Badge</title>
      <link>/posts/microsoft-scout-openclaw-goes-enterprise/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/microsoft-scout-openclaw-goes-enterprise/</guid>
      <description>&lt;p&gt;In March 2026, Satya Nadella told investors that Microsoft could not simply ship OpenClaw internally because doing so &amp;ldquo;would be considered Microsoft launching a virus.&amp;rdquo; Three months later, at Build on June 2, Microsoft shipped exactly that — an autonomous agent built on OpenClaw — and named it Scout. The reversal is the whole story in miniature: the thing that was too ungoverned, too autonomous, too willing to act for an enterprise to touch became shippable the moment Microsoft could wrap it in identity, policy, and audit. Scout is what happens when a self-hosted hacker tool grows a suit and a badge.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Monitor Panels Compared: OLED vs IPS vs VA (and Why Text Clarity Matters)</title>
      <link>/posts/monitor-panel-tech-compared-oled-ips-va/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/monitor-panel-tech-compared-oled-ips-va/</guid>
      <description>&lt;p&gt;Monitors and TVs use the same underlying panel technologies, but the right choice is often the opposite, and the reason is that you sit close and stare at static things. At two feet, you can see individual subpixels, so the &lt;em&gt;layout&lt;/em&gt; of those subpixels changes how crisp text looks. You keep a taskbar, an IDE, or a spreadsheet on screen for hours, so static-element burn-in is a real concern in a way it rarely is on a TV. And you alternate between fast motion (games) and tiny stationary detail (code, cells, UI). A panel that is the obvious winner for a TV in the living room can be the wrong call on a desk. This guide is about the desk.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ovens and Ranges Compared: Gas, Electric, Dual-Fuel, and Induction</title>
      <link>/posts/oven-and-range-types-compared-gas-electric-induction/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/oven-and-range-types-compared-gas-electric-induction/</guid>
      <description>&lt;p&gt;Before comparing fuels and brands, get the categories straight, because the words get used loosely. A &lt;strong&gt;range&lt;/strong&gt; is the all-in-one unit: a cooktop on top and an oven below, in one freestanding or slide-in appliance. A &lt;strong&gt;wall oven&lt;/strong&gt; is just the oven, built into cabinetry at eye level, paired with a separate &lt;strong&gt;cooktop&lt;/strong&gt; dropped into the counter. The range is simpler and cheaper and fits most kitchens; the wall-oven-plus-cooktop split costs more and eats more space but lets you put the oven at a comfortable height and choose each piece independently. Serious bakers often prefer wall ovens because true convection, precise calibration, and premium interior features show up more consistently in that category than in comparable ranges. Decide range vs. split first; then pick how it heats.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pickup Trucks Compared: Ford, Chevy, Ram, and Toyota in 2026</title>
      <link>/posts/pickup-truck-brands-compared-2026/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pickup-truck-brands-compared-2026/</guid>
      <description>&lt;p&gt;The full-size pickup class is close enough in 2026 that there is no bad choice among the big four — only trucks that lean toward different priorities. Ford optimizes for capability and breadth; Chevy and its GMC twin optimize for engine choice and tech; Ram optimizes for ride comfort and interior; Toyota optimizes for its long-run durability reputation. Which one is &amp;ldquo;best&amp;rdquo; depends almost entirely on whether you actually tow near the limit, how much time you spend in the seat, and how long you intend to keep it. This guide compares the half-ton full-size trucks — where most buyers shop — then places the mid-size and electric options around them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Projectors Compared: DLP, LCD, LCoS, and the Best Models for 2026</title>
      <link>/posts/projector-technologies-and-best-projectors-compared/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/projector-technologies-and-best-projectors-compared/</guid>
      <description>&lt;p&gt;A projector is the only practical way to get a 100-plus-inch image, and in 2026 it is a better buy than ever — laser light sources have killed the dreaded lamp replacement, and ultra-short-throw models can sit inches from the wall. But projectors are also where marketing fog is thickest: &amp;ldquo;4K&amp;rdquo; can mean a native 4K panel or a 1080p chip wobbling pixels four times a frame, &amp;ldquo;laser&amp;rdquo; says nothing about contrast, and a spec sheet&amp;rsquo;s lumens number means little once ambient light hits the screen. The two questions that actually decide your picture are &lt;strong&gt;which imaging technology&lt;/strong&gt; the projector uses (it sets the contrast ceiling) and &lt;strong&gt;how much light your room lets you control&lt;/strong&gt; (it sets everything else). Get those two right and the brand and model fall out naturally. This guide untangles the technologies, then names the models worth buying.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Refrigerators Compared: Freestanding, Counter-Depth, Built-In, and Columns</title>
      <link>/posts/refrigerator-types-compared-built-in-counter-depth-column/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/refrigerator-types-compared-built-in-counter-depth-column/</guid>
      <description>&lt;p&gt;A refrigerator decision is really two decisions stacked on top of each other: what &lt;em&gt;format&lt;/em&gt; fits your kitchen and budget, and what &lt;em&gt;brand tier&lt;/em&gt; you are buying into. The format ranges from a freestanding box that rolls in and plugs into the wall, to a fully integrated, panel-matched built-in that disappears into the cabinetry and costs as much as a car. The brand tier ranges from dependable mainstream names to luxury houses whose units are expected to run for two decades. The mistake people make is shopping on door style and finish while ignoring the two things that actually determine how well the appliance does its one job — keeping food fresh — and how long it lasts: the compressor design and the brand&amp;rsquo;s service record.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TV Display Tech Compared: OLED vs QLED vs Mini-LED vs LED</title>
      <link>/posts/tv-display-tech-compared-oled-qled-mini-led/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tv-display-tech-compared-oled-qled-mini-led/</guid>
      <description>&lt;p&gt;The marketing names on a 2026 TV shelf — OLED, QLED, Neo QLED, QD-OLED, Mini-LED, Micro RGB — collapse into a single underlying question: does each pixel make its own light, or is there a separate backlight shining through a liquid-crystal layer? Everything else is a consequence of that one fork. Self-emissive panels (OLED and its variants) give you perfect blacks and per-pixel control at the cost of peak brightness and a small burn-in risk. Backlit panels (everything with &amp;ldquo;LED&amp;rdquo; or &amp;ldquo;QLED&amp;rdquo; in the name) give you searing brightness and zero burn-in at the cost of imperfect blacks and blooming. There is no universally best answer; there is only the best answer for your room and what you watch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What AI Coding Tools Actually Cost: Subscriptions vs Usage vs Raw API in 2026</title>
      <link>/posts/ai-coding-tools-cost-comparison/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ai-coding-tools-cost-comparison/</guid>
      <description>&lt;p&gt;AI coding tools have quietly become one of the larger line items in a developer&amp;rsquo;s monthly software budget, and the pricing has gotten genuinely confusing — the same $20 buys wildly different amounts of work depending on the tool, and the headline subscription price often has little to do with what you actually pay once usage-based billing kicks in. The central decision underneath all of it is the one most people never make deliberately: do you pay a &lt;strong&gt;flat subscription&lt;/strong&gt; that bundles a fixed amount of model usage, pay &lt;strong&gt;per-usage credits&lt;/strong&gt; that meter what you consume, or skip the wrapper entirely and pay &lt;strong&gt;raw API token pricing&lt;/strong&gt; with a bring-your-own-key tool? The answer is not the same for everyone, and getting it wrong can mean either leaving capability on the table or paying several times what you needed to. This guide lays out what each tool costs as of mid-2026, what each price tier can actually accomplish, and — the part that matters most — the real math of subscription versus API.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wiring a Home Remodel for Network: Cable, Drops, Switches, and APs</title>
      <link>/posts/home-remodel-network-wiring-guide/</link>
      <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-remodel-network-wiring-guide/</guid>
      <description>&lt;p&gt;The single most important fact about wiring a remodel is that the walls are open exactly once. While the drywall is off, cable costs a few cents a foot and you can run as much as you want; the day the walls close, every new drop becomes a fishing expedition that costs $200–400 a pop in finished-wall labor. So the governing rule of structured wiring is simple and a little extravagant: &lt;strong&gt;cable is cheap, labor is expensive, and a port you wish you had costs far more than a port you never use.&lt;/strong&gt; Over-provision now. This guide is for the planning stage — deciding what to run where — so the people pulling cable (you or a low-voltage contractor) have a real spec to work from. It pairs with the broader &lt;a href=&#34;/posts/home-network-design/&#34;&gt;home network design&lt;/a&gt; post; here we focus on the physical layer a remodel locks in.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Anycast Explained: One IP Address, Served From Everywhere</title>
      <link>/posts/anycast-explained/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/anycast-explained/</guid>
      <description>&lt;p&gt;The internet&amp;rsquo;s most heavily-used IP addresses — &lt;code&gt;1.1.1.1&lt;/code&gt;, &lt;code&gt;8.8.8.8&lt;/code&gt;, the thirteen DNS root server addresses — are each answered by hundreds of geographically dispersed machines simultaneously. If you send a DNS query to &lt;code&gt;1.1.1.1&lt;/code&gt; from Tokyo, a Cloudflare server in Tokyo responds. If you send the same query from Frankfurt, a server in Frankfurt responds. Both machines use the exact same IP address. There is no DNS-based load balancing here, no NAT, no proxy redirect. The routing fabric of the internet itself is what decides which physical machine you reach — and it does so transparently, at line rate, using a technique called &lt;strong&gt;anycast&lt;/strong&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IPv6 Basics: Why We Need It, How It Differs from IPv4, and What It Unlocks</title>
      <link>/posts/ipv6-basics-and-why-it-matters/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ipv6-basics-and-why-it-matters/</guid>
      <description>&lt;p&gt;For most of the internet&amp;rsquo;s history, IPv6 was the protocol that was perpetually five years away. It was ratified in the late 1990s, everyone agreed it was necessary, and almost nobody deployed it. That era is over. In late March 2026, native IPv6 crossed 50% of Google&amp;rsquo;s global user traffic for the first time, and IPv6 overtook IPv4 as the majority of internet traffic shortly after. In countries like India, France, and Germany, IPv6 penetration is well past 80%. If you build or operate anything on a network, IPv6 is no longer a thing you can defer learning.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Speech-to-Text With Whisper</title>
      <link>/posts/local-speech-to-text-with-whisper/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-speech-to-text-with-whisper/</guid>
      <description>&lt;p&gt;Automatic speech recognition has been a solved problem for cloud services for years, but until Whisper, running genuinely accurate ASR locally required either expensive proprietary software or uncomfortable compromises in accuracy. OpenAI&amp;rsquo;s September 2022 release of Whisper as open-weight software changed that calculus entirely. The model is trained on 680,000 hours of weakly supervised multilingual audio scraped from the web, and it achieves near-human transcription quality on clean English while degrading gracefully — rather than catastrophically — on accented speech, noise, and dozens of other languages. More important for the self-hosted crowd: every weight file is freely downloadable, every inference library is open source, and nothing phones home.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Vector Search for Homelab RAG: pgvector vs Qdrant vs Chroma</title>
      <link>/posts/local-vector-search-pgvector-qdrant-chroma/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-vector-search-pgvector-qdrant-chroma/</guid>
      <description>&lt;p&gt;Running a private retrieval-augmented generation stack means keeping every piece on your own hardware: the language model, the embedding model, and the vector store that ties them together. Most tutorials assume you will reach for a managed API or a hosted vector database, but if your threat model includes data leaving the machine — or you simply refuse to pay per-token for something a modest server can do — you need a stack that works completely offline. That is what this post is about.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Making Tool Calling Reliable on Local Models</title>
      <link>/posts/tool-calling-reliability-local-models/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tool-calling-reliability-local-models/</guid>
      <description>&lt;p&gt;Tool calling is the seam where language models stop being sophisticated autocomplete and start being autonomous agents. A model that can reliably invoke &lt;code&gt;search_web&lt;/code&gt;, &lt;code&gt;run_sql&lt;/code&gt;, or &lt;code&gt;send_email&lt;/code&gt; with well-formed arguments is qualitatively more useful than one that cannot, and the entire agentic software stack — from LangChain orchestrators down to bare MCP servers — treats tool calling as a first-class primitive. The problem is that outside of the frontier cloud APIs, tool calling is fragile by default. Locally-hosted open models, especially those in the 3–14 billion parameter range, fail in ways that surprise developers who are used to GPT-class reliability: they hallucinate function names, produce JSON that is a token or two away from being valid, call tools that should not be called, and skip calls that obviously should happen. Getting this working reliably requires layering several techniques, each of which addresses a different root cause. This post is a practical map of those layers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MTU, MSS, and the Path-MTU Black Hole</title>
      <link>/posts/mtu-mss-and-the-path-mtu-black-hole/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mtu-mss-and-the-path-mtu-black-hole/</guid>
      <description>&lt;p&gt;You spin up a WireGuard tunnel, SSH through it, and the login banner appears. Then you run &lt;code&gt;ls -la&lt;/code&gt; and the terminal freezes. The connection is alive — ping works fine, the handshake completed cleanly — yet any command whose output exceeds a screen or two simply stops arriving. You restart the tunnel, you blame the server, you blame your ISP, and eventually you find a StackExchange answer from 2011 that says &amp;ldquo;just lower your MTU.&amp;rdquo; It works. You have no idea why.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NAT Traversal: STUN, TURN, ICE, and How Peers Punch Through</title>
      <link>/posts/nat-traversal-stun-turn-ice/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nat-traversal-stun-turn-ice/</guid>
      <description>&lt;p&gt;Two devices on opposite sides of the internet want to exchange video frames directly, without routing every packet through a central server. In practice, both are almost certainly behind Network Address Translation — their real addresses are private RFC 1918 space, invisible to the public internet. The internet knows only the public IP of their routers, and those routers have no mapping for unsolicited inbound traffic, so they drop it silently. Neither peer can initiate a connection to the other. This is the NAT deadlock, and it is the normal condition for virtually every laptop, phone, and home server online today.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Preserving a Voice: Fine-Tuning a Local LLM on a Loved One&#39;s Writing</title>
      <link>/posts/fine-tuning-local-llm-loved-ones-voice/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fine-tuning-local-llm-loved-ones-voice/</guid>
      <description>&lt;p&gt;If you have recovered a parent&amp;rsquo;s old laptop and found years of their writing on it — daily entries, a blog kept through an illness, the accumulated texture of how they thought and spoke — it is now technically possible to fine-tune a language model that writes in their voice, run it entirely on hardware you own, and share it with your family. None of that requires a research lab or a cloud account. The hardware most enthusiasts already have is more than enough. The harder parts are not the GPU or the training command; they are the data preparation, the honest framing of what the result actually is, and the decisions you make so that the thing you build is durable, private, and kind to the people who will use it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>traceroute, ping, and the Network Troubleshooting Toolkit</title>
      <link>/posts/traceroute-ping-and-the-network-troubleshooting-toolkit/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/traceroute-ping-and-the-network-troubleshooting-toolkit/</guid>
      <description>&lt;p&gt;Every sysadmin has typed &lt;code&gt;ping 8.8.8.8&lt;/code&gt; as a reflex. Most have followed it with &lt;code&gt;traceroute&lt;/code&gt; when ping didn&amp;rsquo;t clear things up, squinted at a column of asterisks, and declared the network &amp;ldquo;probably fine.&amp;rdquo; What separates the person who diagnoses a problem in three minutes from the one who spends an hour chasing the wrong hop is not a different set of tools — it is understanding what each tool is actually measuring, where it lies, and what the output genuinely cannot tell you. The core diagnostic tools are old, nearly universal, and widely misread. Getting precise about their mechanics pays for itself every time the network is misbehaving at 2 a.m.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What Happens When You Type a URL and Press Enter</title>
      <link>/posts/what-happens-when-you-type-a-url/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/what-happens-when-you-type-a-url/</guid>
      <description>&lt;p&gt;The question sounds almost trivially simple: you type &lt;code&gt;https://example.com/path?q=foo&lt;/code&gt; into a browser and hit Enter. A fraction of a second later, a rendered page appears. That fraction of a second, however, contains somewhere between a dozen and a hundred distinct network and system events, many of them occurring in parallel, several of them short-circuited by caches you never think about. The full answer touches operating-system internals, cryptographic key exchange, autonomous system routing policy, content delivery architectures, and compiler-style tree construction in the browser engine. It is one of the richest questions in applied computing, which is why it has been a favourite job-interview topic for more than two decades.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hermes Agent Comes to the Desktop: Install, Optimization, and the Best Local Models</title>
      <link>/posts/hermes-desktop-app-deep-dive/</link>
      <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hermes-desktop-app-deep-dive/</guid>
      <description>&lt;p&gt;When Nous Research released Hermes Agent in February 2026, it was a terminal animal: a single curl command, a config file, and a chat loop in your shell. The pitch was unusual even by 2026 standards — an autonomous agent with a genuine &lt;em&gt;learning loop&lt;/em&gt; that writes its own skills, refines them during use, and builds a deepening model of who you are across sessions. The catch was that you had to live in a TUI to use it. On June 3rd that changed: Nous shipped &lt;strong&gt;Hermes Desktop&lt;/strong&gt;, a native cross-platform front end (currently build v0.15.2, in public preview) that was first demoed during Jensen Huang&amp;rsquo;s GTC keynote and brings the agent out of the terminal without changing what it is underneath.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Jan: The Open-Source Local LLM Runner Coming for Ollama and LM Studio</title>
      <link>/posts/jan-local-llm-runner/</link>
      <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/jan-local-llm-runner/</guid>
      <description>&lt;p&gt;For two years the local-LLM conversation came down to a fork in the road: Ollama if you live in a terminal and want a daemon you can script, LM Studio if you want a polished desktop app to click around in. Both work. Both have a catch. Ollama&amp;rsquo;s UX is thin and its model packaging is its own walled garden; LM Studio is closed-source and you are trusting a binary blob with your prompts. &lt;strong&gt;Jan&lt;/strong&gt; is the project that looked at both and asked why you should have to choose between an open license, a real GUI, and a server you can point your code at.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Routers Inside the Enterprise: What They Do Besides Reach the Internet</title>
      <link>/posts/routers-inside-the-enterprise/</link>
      <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/routers-inside-the-enterprise/</guid>
      <description>&lt;p&gt;Ask someone what a router does and you&amp;rsquo;ll usually hear some version of &amp;ldquo;it connects your network to the internet.&amp;rdquo; That is true, and it is also the least interesting thing a router does. In a home, the router at the edge is the only router you have, so it&amp;rsquo;s easy to conclude that reaching the internet is the whole job. In a company network with thousands of devices across dozens of subnets and several buildings, routing happens constantly &lt;em&gt;inside&lt;/em&gt; the building, between segments that never touch the public internet at all. The internet uplink is one port on one device; the routing that keeps the company running is everywhere else.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Subnetting Explained: Why Subnet Masks Aren&#39;t Just 255s and 0s</title>
      <link>/posts/subnetting-beyond-the-octet-boundary/</link>
      <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/subnetting-beyond-the-octet-boundary/</guid>
      <description>&lt;p&gt;Most people meet subnet masks as a string of numbers that are always either 255 or 0 — &lt;code&gt;255.255.255.0&lt;/code&gt;, &lt;code&gt;255.255.0.0&lt;/code&gt; — and they reasonably conclude that those are the only shapes a mask comes in. Then one day they see &lt;code&gt;255.255.255.192&lt;/code&gt; on a real router, or a &lt;code&gt;/26&lt;/code&gt; in a ticket, and the whole mental model wobbles. What is a 192 doing in there? Is that even allowed? It looks like a typo.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Active Directory Domain Services Fundamentals</title>
      <link>/posts/active-directory-domain-services-fundamentals/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/active-directory-domain-services-fundamentals/</guid>
      <description>&lt;p&gt;If you have spent your career in Linux, Active Directory is the system you have managed to avoid understanding while still tripping over it constantly. It is the thing the Windows team runs that your SSH logins somehow depend on, the reason a &amp;ldquo;domain controller being down&amp;rdquo; can stop people from logging into machines that have nothing to do with Windows, the black box behind &amp;ldquo;just use your AD credentials.&amp;rdquo; This post is the model you have been missing — AD explained in terms you already know, without pretending you have never seen a directory service before.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apache CloudStack: The Underrated Workhorse</title>
      <link>/posts/apache-cloudstack-underrated-workhorse/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apache-cloudstack-underrated-workhorse/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;/posts/openstack-full-reference-cloud/&#34;&gt;previous post in this series&lt;/a&gt; made the case that OpenStack is the closest thing to a private AWS and that the price of admission is an operational complexity that sinks roughly half the teams who attempt it. If you read that and thought &amp;ldquo;I want a real cloud — self-service, multi-tenant, API-driven, with a scheduler that places VMs for me — but I do not have a three-to-eight-person platform team to keep thirty microservices alive,&amp;rdquo; this post is for you. Apache CloudStack is the platform that occupies exactly that gap, and it is the most consistently underrated piece of infrastructure software in the open-source cloud world.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ASP.NET Core Web Development Primer</title>
      <link>/posts/aspnet-core-web-development-primer/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aspnet-core-web-development-primer/</guid>
      <description>&lt;p&gt;If your mental model of .NET is still &amp;ldquo;Windows-only, IIS, Visual Studio, and a lot of XML,&amp;rdquo; it is a decade out of date. Modern ASP.NET Core is a cross-platform, open-source, genuinely fast web framework that runs the same on Linux, macOS, and Windows, deploys happily in a container, and is built command-line-first. This post is a primer for engineers who already know how to build a backend somewhere else — Go, Node/Express, Python/FastAPI, Java/Spring — and want the shape of ASP.NET Core without wading through beginner tutorials.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Choosing a Linux Distribution: A Field Guide</title>
      <link>/posts/choosing-a-linux-distribution/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/choosing-a-linux-distribution/</guid>
      <description>&lt;p&gt;The Linux distribution landscape looks overwhelming from the outside — DistroWatch lists hundreds of them, forum arguments never resolve, and every community insists their choice is the only rational one. The reality is more boring and more useful: most of the choice that actually matters reduces to three variables — release model, governance structure, and ecosystem fit for your workload. The cosmetic differences (default desktop, color scheme, forum culture) are near-irrelevant for anything running headless or in a container, and even on the desktop they fade within a week of customization. What does not fade is the pain of running a distribution whose release cadence fights your stability requirements, or whose package manager lacks the software stack your application demands, or whose corporate parent has just pulled the source code rug out from under the community.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cloud Security Posture Management</title>
      <link>/posts/cloud-security-posture-management/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cloud-security-posture-management/</guid>
      <description>&lt;p&gt;The headline cloud breaches of the past decade were not won by nation-state exploit chains or novel zero-days. They were won by attackers who found an S3 bucket with &lt;code&gt;acl: public-read&lt;/code&gt;, an IAM role with &lt;code&gt;Action: &amp;quot;*&amp;quot;&lt;/code&gt;, or a security group with &lt;code&gt;0.0.0.0/0&lt;/code&gt; on port 22 — and walked right in. Misconfiguration is the dominant attack vector in cloud environments. One 2025 study pegged it as responsible for 99% of cloud security failures, with organizations averaging over 3,000 misconfigured assets at any given time and a mean detection time of 241 days. The cloud&amp;rsquo;s shared-responsibility model makes this entirely your problem: AWS, Azure, and GCP handle the security of the cloud. You handle security in the cloud — meaning every IAM policy, every storage ACL, every network rule, and every logging switch you leave in its default state is your liability.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Consensus and Coordination: Raft, Paxos, and Why Agreement Is Hard</title>
      <link>/posts/consensus-coordination-raft-paxos/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/consensus-coordination-raft-paxos/</guid>
      <description>&lt;p&gt;Underneath an enormous amount of the infrastructure you run every day sits a single, deceptively hard problem: getting a group of machines to &lt;em&gt;agree&lt;/em&gt; on something. Which node is the leader. What the next entry in the log is. Whether a transaction committed. This is the &lt;strong&gt;consensus&lt;/strong&gt; problem, and it is the beating heart of etcd (which holds all of Kubernetes&amp;rsquo; state), Consul, ZooKeeper, Kafka&amp;rsquo;s metadata layer, and every distributed database with a notion of &amp;ldquo;the truth.&amp;rdquo; If you understand consensus, a huge swath of distributed systems stops being mysterious. This post builds that understanding from the ground up — not the proofs, but the &lt;em&gt;intuitions&lt;/em&gt; an engineer needs to reason about these systems when they misbehave.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Consistency, CAP, and Replication: The Tradeoffs You Cannot Escape</title>
      <link>/posts/consistency-cap-replication/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/consistency-cap-replication/</guid>
      <description>&lt;p&gt;The moment you keep more than one copy of your data — for durability, for read scaling, for surviving a datacenter loss — you inherit a set of trade-offs that no amount of engineering can make disappear. They are not bugs to be fixed; they are consequences of physics and logic. This post maps those trade-offs: what consistency models actually promise, what CAP and its sharper successor PACELC really say, how the three replication architectures behave, and how real databases pick their spot. The goal is that &amp;ldquo;eventually consistent&amp;rdquo; stops being a vague warning label and becomes a precise, costed engineering choice.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Containerlab: Network Labs in Containers</title>
      <link>/posts/containerlab-network-labs-in-containers/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/containerlab-network-labs-in-containers/</guid>
      <description>&lt;p&gt;Network engineers have always had a testing problem. The real protocols — &lt;a href=&#34;/posts/bgp-for-engineers/&#34;&gt;BGP for engineers&lt;/a&gt;, OSPF, IS-IS, EVPN/VXLAN — only reveal their behavior under actual control-plane stress. Packet tracers and GUI simulators paper over the details that matter in production. The traditional answer has been GNS3 or EVE-NG: grab some vendor qcow2 images, wrestle them into a topology canvas with a mouse, wait several minutes while full VM instances boot, and then hope the emulated dataplane is close enough to the hardware you&amp;rsquo;re targeting. That workflow is better than nothing, but it carries a ceiling. Topologies are not version-controlled. Spinning up a fresh lab for each CI run is impractical. Sharing a reproducible environment with a colleague means exporting and transferring multi-gigabyte project archives. Containerlab breaks that ceiling by treating network topology as code — a plain YAML file you can &lt;code&gt;git commit&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;, and &lt;code&gt;deploy&lt;/code&gt; in seconds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Digital Forensics and Memory Analysis</title>
      <link>/posts/digital-forensics-and-memory-analysis/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/digital-forensics-and-memory-analysis/</guid>
      <description>&lt;p&gt;Digital forensics is the discipline of turning a compromised host into a clear, defensible account of what happened — who got in, how, what they touched, and what they left behind. Done correctly, it produces evidence that holds up under scrutiny: in an internal post-mortem, in a legal proceeding, in a regulatory audit. Done sloppily, it produces a story that a competent adversary&amp;rsquo;s lawyer, or your own incident review board, will dismantle. The difference between the two is not primarily tooling — it is discipline. Discipline about the order in which you collect evidence, discipline about not touching source media, discipline about documenting every action you take, and discipline about keeping a hash chain that proves the evidence you analyzed is identical to the evidence you collected.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Distributed SQL: CockroachDB, TiDB, and YugabyteDB</title>
      <link>/posts/distributed-sql-cockroachdb-tidb-yugabytedb/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/distributed-sql-cockroachdb-tidb-yugabytedb/</guid>
      <description>&lt;p&gt;For two decades the database world told you to pick two of three: SQL with its joins and transactions, horizontal scale across many machines, or strong consistency that never lies to you. Relational databases gave you SQL and consistency on one big box; the NoSQL wave gave you scale by throwing out SQL and relaxing consistency. The thing nobody could sell you was all three at once — a database you could shard across a dozen machines, lose one to a backhoe, and still run &lt;code&gt;BEGIN; ... COMMIT;&lt;/code&gt; against, with serializable guarantees, as if nothing happened.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Firecracker and the microVM</title>
      <link>/posts/firecracker-and-the-microvm/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/firecracker-and-the-microvm/</guid>
      <description>&lt;p&gt;A Linux container is not a security boundary you should bet a multi-tenant platform on. It is a bundle of namespaces and cgroups sharing one host kernel, and when that kernel has a bug — runc alone shipped three fresh container escapes in late 2025 — the namespace wall is exactly as strong as the kernel underneath it, which is to say: not a wall, a curtain. The &lt;a href=&#34;/posts/gvisor-kata-containers-sandboxed-runtimes/&#34;&gt;sandboxed-runtimes post&lt;/a&gt; opened on this problem. This post is about the answer that won: give every untrusted workload its &lt;em&gt;own&lt;/em&gt; kernel, inside a real hardware-virtualized VM, but make that VM so small and so fast that it feels like a container.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fortran Is Not Dead</title>
      <link>/posts/fortran-is-not-dead/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fortran-is-not-dead/</guid>
      <description>&lt;p&gt;Every few years someone publishes a piece titled &amp;ldquo;Fortran is dead&amp;rdquo; or &amp;ldquo;Why is Fortran still used?&amp;rdquo; — and every time, the answer is the same: because it runs things that cannot afford to be wrong. The European Centre for Medium-Range Weather Forecasts Integrated Forecasting System (IFS), which produces the best global weather predictions on Earth, is written primarily in Fortran. So is the Weather Research and Forecasting (WRF) model used operationally by national meteorological agencies worldwide. BLAS and LAPACK — the linear algebra libraries that underpin NumPy, SciPy, MATLAB, R, and nearly every ML framework that touches a dense matrix — trace their lineage directly to Fortran implementations. The DOE national laboratories run multi-decade fusion, climate, and astrophysics codes in Fortran, validated against physical experiments and peer-reviewed numerical theory. When you call &lt;code&gt;numpy.dot()&lt;/code&gt; on a large matrix, you are, at some level, calling Fortran.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FreeBSD and OpenBSD for the Linux Admin</title>
      <link>/posts/freebsd-and-openbsd-for-the-linux-admin/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/freebsd-and-openbsd-for-the-linux-admin/</guid>
      <description>&lt;p&gt;If you have spent your career on Linux, the BSDs feel close enough to be familiar and different enough to be confusing. Same shell, same &lt;code&gt;ls -l&lt;/code&gt;, same SSH, the same general Unix muscle memory — and then you go looking for &lt;code&gt;systemctl&lt;/code&gt;, &lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;/etc/netplan&lt;/code&gt;, or a kernel that is one package among thousands, and none of it is there. The reflex is to call this &amp;ldquo;Linux with the furniture rearranged.&amp;rdquo; That reflex is wrong, and getting past it is the whole point of this post.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Frigate: AI-Powered NVR</title>
      <link>/posts/frigate-ai-powered-nvr/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/frigate-ai-powered-nvr/</guid>
      <description>&lt;p&gt;Cloud camera subscriptions have normalized a model where you pay monthly for the privilege of having a corporation analyze footage of your home, store it on their servers, and potentially hand it to law enforcement with or without your knowledge. Ring and Google Nest have made this arrangement feel ordinary. It is not. You are paying recurring fees for a service with worse detection latency than local inference, a privacy posture you have no control over, and a dependency on vendor uptime that has already produced outages during which cameras silently stopped recording. Frigate is the serious alternative: a self-hosted, open-source network video recorder built from the ground up around real-time object detection, with no cloud dependency and latency measured in milliseconds from event to notification.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GCP for the AWS-Fluent Engineer</title>
      <link>/posts/gcp-for-the-aws-fluent-engineer/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gcp-for-the-aws-fluent-engineer/</guid>
      <description>&lt;p&gt;AWS is the default. If you have spent the last several years building infrastructure on Amazon, you carry a mental model — accounts, IAM policies, VPCs, regions, S3, Lambda — that is deeply useful and occasionally a liability when you step into Google Cloud. GCP is not a worse or better AWS; it is a different set of opinions, some of them genuinely superior, some of them frustrating, and a few of them so different from what you know that they will silently mislead you if you assume the analogy holds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GitLab Self-Hosted</title>
      <link>/posts/gitlab-self-hosted/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gitlab-self-hosted/</guid>
      <description>&lt;p&gt;GitLab is not a git forge with CI bolted on. It is an attempt to replace your entire software delivery toolchain with a single, opinionated platform: source control, CI/CD, container registry, package registry, issue tracking, wikis, environments, deployments, and a growing suite of security scanning tools — all in one process bundle, sharing one configuration file, one PostgreSQL instance, and one authentication system. That integration is both its greatest strength and the reason a base installation consumes more RAM than some teams&amp;rsquo; entire Kubernetes nodes. Before you reach for it, you need to know what you are actually running.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Graph Databases with Neo4j</title>
      <link>/posts/graph-databases-with-neo4j/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/graph-databases-with-neo4j/</guid>
      <description>&lt;p&gt;Most data has always been a graph. Customers know each other. Accounts share devices. Products are purchased together. Infrastructure components depend on each other in chains three layers deep. Relational databases have modeled this for decades — foreign keys, junction tables, recursive CTEs — and for shallow, well-bounded relationships the relational model is fine. Then the depth increases. You need to find every account within four hops of a flagged entity. You need to know which packages transitively depend on a vulnerable library. You need to recommend items based on a customer&amp;rsquo;s behavioral neighborhood, not just their own history. At that point the relational model starts to strain, and the question becomes whether the strain is worth the cost of adding another datastore.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Group Policy in Practice</title>
      <link>/posts/group-policy-in-practice/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/group-policy-in-practice/</guid>
      <description>&lt;p&gt;If Active Directory is how a Windows organization models &lt;em&gt;who&lt;/em&gt; people are, Group Policy is how it controls &lt;em&gt;what their machines do&lt;/em&gt;. It is the configuration-management system that predates Ansible, Puppet, and the entire &amp;ldquo;infrastructure as code&amp;rdquo; movement by years, and it is still the thing keeping the lights on in the overwhelming majority of Windows estates. For a Linux admin, the closest mental hook is a configuration-management tool — but one that is pull-based, runs on a schedule you mostly cannot see, targets an LDAP directory tree instead of an inventory file, and has been accreting since 2000. Understanding it is less about learning a tool and more about understanding a processing model and the sprawl that model produces over two decades.&lt;/p&gt;</description>
    </item>
    <item>
      <title>gRPC From the Ground Up</title>
      <link>/posts/grpc-from-the-ground-up/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grpc-from-the-ground-up/</guid>
      <description>&lt;p&gt;gRPC has been in production at Google-scale since 2015 and has become the dominant RPC framework for polyglot microservice systems — but most introductions treat it as &amp;ldquo;REST with Protobuf,&amp;rdquo; which misses the point entirely. The protocol is built directly on HTTP/2, and that foundation is what enables multiplexed bidirectional streaming, first-class deadline propagation, and generated strongly-typed stubs across a dozen languages from a single schema. The tradeoff is real: binary framing, a non-trivial toolchain, load-balancing behavior that surprises engineers coming from stateless HTTP/1.1 services, and genuine friction in browsers. Understanding the transport layer is not optional background knowledge — it is the key to understanding why gRPC works the way it does, and why certain failure modes appear where they do.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Guardrails for Production LLM Applications</title>
      <link>/posts/guardrails-for-production-llm-applications/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/guardrails-for-production-llm-applications/</guid>
      <description>&lt;p&gt;The companion post to this one made an uncomfortable argument: prompt injection has no patch, because the vulnerability is the architecture of language models themselves. To a model, your instructions and an attacker&amp;rsquo;s instructions are the same tokens, and no filter closes that hole completely. If you have not read it, the short version is that you must &lt;strong&gt;assume the model can be subverted&lt;/strong&gt; and design so that a subverted model cannot do much damage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Handheld Linux Showdown: Bazzite vs CachyOS vs SteamOS on the ROG Ally</title>
      <link>/posts/handheld-linux-showdown-bazzite-cachyos-steamos/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/handheld-linux-showdown-bazzite-cachyos-steamos/</guid>
      <description>&lt;p&gt;The ROG Ally is no longer a Windows-only device in any meaningful sense. With Valve&amp;rsquo;s release of SteamOS 3.9 in April 2026 officially extending support to third-party AMD handhelds, the Ally joins a maturing Linux handheld ecosystem that already had two strong contenders: Bazzite, the immutable Fedora Atomic gaming image from the Universal Blue project, and CachyOS Handheld Edition, the performance-obsessed Arch derivative with a custom kernel and the LAVD scheduler baked in. All three converge on the same underlying enabling stack — Gamescope as the Wayland compositor and session manager, Handheld Daemon (HHD) for TDP and controller abstraction, and Decky Loader for plugin-based extensibility — but they diverge sharply in lineage, update model, hardware support maturity, and the implied relationship between the user and their OS.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Harvester: Cloud-Native HCI on Bare Metal</title>
      <link>/posts/harvester-cloud-native-hci/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/harvester-cloud-native-hci/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;/posts/opennebula-pragmatic-private-cloud/&#34;&gt;previous post&lt;/a&gt; covered OpenNebula, which wins by being &lt;em&gt;small&lt;/em&gt;. Harvester is the opposite bet. Where OpenNebula folds cloud responsibilities into few moving parts, Harvester embraces the most elaborate substrate in modern infrastructure — Kubernetes — and builds an entire hyperconverged virtualization platform on top of it. The payoff is the most architecturally current design in this series: VMs and containers as first-class citizens on the same cluster, the Kubernetes scheduler placing your workloads, and a declarative API for everything. The cost is that you inherit Kubernetes&amp;rsquo; operational weight whether you wanted it or not. This post is about when that trade is brilliant and when it is overkill.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Incus and LXD: The Lightweight Cluster That Auto-Places</title>
      <link>/posts/incus-and-lxd-lightweight-cluster/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/incus-and-lxd-lightweight-cluster/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;/posts/apache-cloudstack-underrated-workhorse/&#34;&gt;previous post&lt;/a&gt; argued that Apache CloudStack gives you a genuine multi-tenant IaaS cloud with a fraction of OpenStack&amp;rsquo;s operational weight, and ended by pointing at a class of user for whom even CloudStack is more than they need: someone running mostly-Linux workloads, for a single team or a small set of trusted users, who wants the lightest possible path to &lt;em&gt;self-service with automatic placement&lt;/em&gt; — provision an instance, have the platform pick the best host, no babysitting. That is the Incus and LXD sweet spot, and it is a genuinely different shape of tool from everything else in this series.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integrating Linux with Active Directory</title>
      <link>/posts/integrating-linux-with-active-directory/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/integrating-linux-with-active-directory/</guid>
      <description>&lt;p&gt;This is the post the rest of the series was building toward. The earlier pieces explained Active Directory from the outside — &lt;a href=&#34;/posts/active-directory-domain-services-fundamentals/&#34;&gt;the directory itself&lt;/a&gt;, &lt;a href=&#34;/posts/group-policy-in-practice/&#34;&gt;Group Policy&lt;/a&gt;, &lt;a href=&#34;/posts/kerberos-and-windows-authentication/&#34;&gt;Kerberos&lt;/a&gt;, and &lt;a href=&#34;/posts/powershell-for-administrators/&#34;&gt;PowerShell&lt;/a&gt; — because to integrate Linux with AD you have to understand what AD actually is. Now we make a Linux box authenticate against that directory, so a user&amp;rsquo;s one corporate identity logs them into Windows desktops, Linux servers, and everything in between. One identity, one password, one place to disable an account when someone leaves. That last point is the real prize: in a mixed shop, the alternative to AD integration is local accounts scattered across every Linux host, which is an offboarding nightmare and an audit failure waiting to happen.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kerberos and Windows Authentication</title>
      <link>/posts/kerberos-and-windows-authentication/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kerberos-and-windows-authentication/</guid>
      <description>&lt;p&gt;Every Linux admin has met Kerberos, usually at the moment it breaks SSH and they discover that the GSSAPI auth they enabled depends on a ticket they do not have. The MIT Kerberos you half-learned and the Kerberos inside Active Directory are the same protocol — AD&amp;rsquo;s domain controllers &lt;em&gt;are&lt;/em&gt; Kerberos KDCs, as the &lt;a href=&#34;/posts/active-directory-domain-services-fundamentals/&#34;&gt;fundamentals post&lt;/a&gt; laid out. What makes the Windows version worth a dedicated treatment is not the protocol mechanics, which are classic and elegant, but the &lt;em&gt;attacks&lt;/em&gt; — a whole taxonomy of credential abuse that exploits exactly how AD implements tickets, and that every defender needs to recognize on sight because they are the bread and butter of every real-world domain compromise.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Knative: Serverless on Your Own Cluster</title>
      <link>/posts/knative-serverless-on-your-own-cluster/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/knative-serverless-on-your-own-cluster/</guid>
      <description>&lt;p&gt;Cloud Run solved a real problem: you give Google a container image and a concurrency target, and the platform handles everything else — routing, scale-to-zero, traffic splitting, cold starts, revisions. The contract is clean and the operational burden is near-zero. The catch is that you are running on Google&amp;rsquo;s infrastructure, speaking Google&amp;rsquo;s API surface, at Google&amp;rsquo;s pricing. If you are already running &lt;a href=&#34;/posts/kubernetes-basics/&#34;&gt;Kubernetes&lt;/a&gt; and want that same serverless developer experience without the managed-cloud lock-in, the answer the ecosystem converged on is &lt;strong&gt;Knative&lt;/strong&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>KubeVirt: Running VMs on Kubernetes</title>
      <link>/posts/kubevirt-running-vms-on-kubernetes/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubevirt-running-vms-on-kubernetes/</guid>
      <description>&lt;p&gt;The software-defined datacenter has been promising a unified control plane for containers and VMs for a decade, and for most of that decade it delivered the promise as a Venn diagram with two separate circles. You ran Kubernetes for your microservices and vSphere (or oVirt, or Proxmox) for your VMs, and somewhere in the middle there was a CMDB and a prayer. &lt;strong&gt;KubeVirt&lt;/strong&gt; is the serious attempt to close that gap from the Kubernetes side: a set of custom resource definitions and controllers that let you express a virtual machine as a Kubernetes object, schedule it with the same kube-scheduler that handles your pods, and manage its lifecycle with &lt;code&gt;kubectl&lt;/code&gt; and &lt;code&gt;virtctl&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kyverno vs OPA Gatekeeper</title>
      <link>/posts/kyverno-vs-opa-gatekeeper/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kyverno-vs-opa-gatekeeper/</guid>
      <description>&lt;p&gt;Every Kubernetes cluster is a shared surface. Left to its own defaults, it will happily schedule containers running as root, pull images from any registry on the internet, spin up namespaces with no resource quotas, and generally do whatever the submitting developer asked — because its job is to run workloads, not second-guess them. That is exactly right for a single-team cluster where everyone is trusted. It is a serious problem everywhere else: multi-tenant platforms, production environments with compliance requirements, shared developer clusters where a careless &lt;code&gt;kubectl apply&lt;/code&gt; can destabilize a neighbor.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MAAS: Bare-Metal as a Service</title>
      <link>/posts/maas-bare-metal-as-a-service/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/maas-bare-metal-as-a-service/</guid>
      <description>&lt;p&gt;Every other platform in this &lt;a href=&#34;/posts/private-cloud-on-your-own-hardware/&#34;&gt;private-cloud series&lt;/a&gt; starts from the same unspoken assumption: you already have a pile of servers with an operating system installed, and the question is how to turn them into a cloud. MAAS asks the question one layer down. What turns the &lt;em&gt;bare metal&lt;/em&gt; itself — racks of machines with nothing on the disks — into a pool you allocate from on demand? That is the gap MAAS fills, and it is why MAAS does not really compete with OpenStack or Proxmox so much as sit &lt;em&gt;underneath&lt;/em&gt; them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Making Proxmox Cloud-Like: OpenTofu, the API, and the Placement Gap</title>
      <link>/posts/making-proxmox-cloud-like/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/making-proxmox-cloud-like/</guid>
      <description>&lt;p&gt;Most of this series has been a tour of platforms you would &lt;em&gt;migrate to&lt;/em&gt;: &lt;a href=&#34;/posts/openstack-full-reference-cloud/&#34;&gt;OpenStack&lt;/a&gt; and &lt;a href=&#34;/posts/apache-cloudstack-underrated-workhorse/&#34;&gt;CloudStack&lt;/a&gt; as full clouds, &lt;a href=&#34;/posts/incus-and-lxd-lightweight-cluster/&#34;&gt;Incus&lt;/a&gt; as the lightweight cluster that auto-places, &lt;a href=&#34;/posts/xcp-ng-and-xen-orchestra-xenserver-successor/&#34;&gt;XCP-ng&lt;/a&gt; as the Xen successor. This post is for the much larger group of readers who are not migrating anywhere. You already run &lt;strong&gt;Proxmox VE&lt;/strong&gt;. It works. The cluster is healthy, Ceph is humming, backups land every night, and the last thing you want is to rip out a platform your team actually understands.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Matrix and Synapse: Self-Hosted Chat</title>
      <link>/posts/matrix-and-synapse-self-hosted-chat/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/matrix-and-synapse-self-hosted-chat/</guid>
      <description>&lt;p&gt;Matrix is not a chat application. It is a protocol — an open standard for federated, real-time communication — and that distinction matters enormously when you are deciding whether to run it. Slack is a product, Discord is a product, and Signal is a product. Matrix is infrastructure, more analogous to email than to any of those things. When you deploy a Matrix homeserver, you are not just spinning up a private chat app for your family or team; you are joining a global, decentralized mesh of servers that all speak the same protocol, federate state with each other, and collectively guarantee that no single entity controls the conversation. That is the promise, and for a certain class of operator it is a genuinely compelling one. The caveat is that the reference implementation — Synapse — is a Python service with a reputation for eating RAM, the encryption UX still has sharp edges that confuse non-technical users, and running bridges to WhatsApp, Signal, or Discord introduces fragility that compounds over time. This post covers all of it honestly: how the protocol works, how to deploy a production-grade homeserver, what the lighter alternatives look like in 2026, and when the entire stack is simply not worth the effort.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modern C in 2026 (C23)</title>
      <link>/posts/modern-c-2026-c23/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-c-2026-c23/</guid>
      <description>&lt;p&gt;C is the language everything compiles down to — or compiles &lt;em&gt;through&lt;/em&gt;. The Linux kernel, every major operating system core, virtually every cryptographic library, every language runtime that matters, and the firmware running inside the device you are reading this on is C. It is also a language where a single typo can corrupt memory silently, hand an attacker shell, and leave no trace in the process. The C23 standard — officially ISO/IEC 9899:2024, published October 2024 — is the most significant revision since C11, addressing a surprising number of these footguns while adding genuinely useful primitives. But the standard by itself does not make C safe. The modern answer is layered: a better language standard, a disciplined compiler flag set, dynamic instrumentation through sanitizers, and coverage-guided fuzzing that lets machines find the bugs your eyes miss.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modern C&#43;&#43; (C&#43;&#43;20/23)</title>
      <link>/posts/modern-cpp-20-23/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-cpp-20-23/</guid>
      <description>&lt;p&gt;C++ in 2026 is genuinely a different language from what was taught in universities through most of the 2010s. The additions accumulated across C++11, C++14, C++17, C++20, and C++23 have reshaped the idioms, the error model, and the library surface to a degree that a careful C++23 codebase bears only superficial resemblance to the raw-pointer, &lt;code&gt;std::enable_if&lt;/code&gt;-riddled templates and &lt;code&gt;printf&lt;/code&gt;-formatted output of legacy codebases. That transformation is real and worth understanding. But so is the honest caveat: the language accreted all of this on top of a 40-year substrate. Complexity is not shrinking. The build tooling and packaging ecosystem is still catching up to what Go and Rust shipped from day one. And the safety model — for all its RAII discipline and smart-pointer conventions — remains fundamentally opt-in in ways that Rust&amp;rsquo;s borrow checker is not.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MongoDB Done Right</title>
      <link>/posts/mongodb-done-right/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mongodb-done-right/</guid>
      <description>&lt;p&gt;MongoDB spent the 2010s as the database everyone loved to mock — &amp;ldquo;/dev/null is web scale,&amp;rdquo; schemaless data that rotted into mush, a default configuration that lost writes. A decade later most of those jokes are about a product that no longer exists. Modern MongoDB has multi-document ACID transactions, schema validation, a real query optimizer, and durability defaults that acknowledge to a majority of nodes. The hype died and the database grew up, and the interesting question now is not &amp;ldquo;is MongoDB a toy?&amp;rdquo; but &amp;ldquo;what is it genuinely good at, and how do you avoid the specific ways it still bites people?&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>NATS: The Cloud-Native Nervous System</title>
      <link>/posts/nats-cloud-native-nervous-system/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nats-cloud-native-nervous-system/</guid>
      <description>&lt;p&gt;Most messaging systems are shaped like the problem they were designed to solve in a specific decade. RabbitMQ was shaped by enterprise Java and AMQP routing needs circa 2007. Kafka was shaped by LinkedIn&amp;rsquo;s append-only log problem circa 2011. Both are excellent at what they were designed for, and both carry the operational weight of that origin — broker clusters, coordination services, schema registries.&lt;/p&gt;&#xA;&lt;p&gt;NATS came from a different angle. Apcera built it in 2010 for platform-as-a-service orchestration, where you needed &lt;em&gt;every process&lt;/em&gt; talking to &lt;em&gt;every other process&lt;/em&gt; with minimum overhead and zero configuration drift. The result is a server that compiles to a single Go binary with no external dependencies, boots in milliseconds, and routes messages through a subject hierarchy clean enough to draw on a whiteboard. Over time NATS grew a full persistence and streaming layer (JetStream), a distributed KV and object store, a leaf-node topology for edge deployments, and a cryptographic security model built on NaCl keypairs. It remains a single binary.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenNebula: The Pragmatic Private Cloud</title>
      <link>/posts/opennebula-pragmatic-private-cloud/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opennebula-pragmatic-private-cloud/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;/posts/private-cloud-on-your-own-hardware/&#34;&gt;series intro&lt;/a&gt; we drew a line through the whole field with one test: does the platform have a &lt;em&gt;placement scheduler&lt;/em&gt; — the component that, when you ask for a VM, decides on its own which physical host should run it? That test is what separates a cloud platform from a cluster manager. OpenStack passes it and makes you pay in operational complexity. Proxmox mostly fails it and is pleasant to run. OpenNebula is the interesting middle: it passes the test — it has a genuine scheduler, multi-tenancy, quotas, an API, and a web UI — and yet a single person can stand it up in an afternoon and keep it running without a platform team.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenStack: The Full Reference Cloud (and What It Costs You)</title>
      <link>/posts/openstack-full-reference-cloud/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/openstack-full-reference-cloud/</guid>
      <description>&lt;p&gt;If the &lt;a href=&#34;/posts/private-cloud-on-your-own-hardware/&#34;&gt;private-cloud intro&lt;/a&gt; asked &amp;ldquo;what would it take to rebuild AWS on your own hardware,&amp;rdquo; OpenStack is the platform that answers &amp;ldquo;all of it, and here is the bill.&amp;rdquo; It is the most complete, most powerful, and most operationally demanding option in this entire series — the only one that genuinely tries to reproduce &lt;em&gt;every&lt;/em&gt; capability from the intro&amp;rsquo;s eight-item table, at a scale that runs CERN and Walmart. It is also the platform most likely to defeat a team that underestimates it. This post is an honest accounting of both halves: the staggering power, and the staggering price.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Oracle Cloud&#39;s Always-Free ARM Tier</title>
      <link>/posts/oracle-cloud-always-free-arm-tier/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/oracle-cloud-always-free-arm-tier/</guid>
      <description>&lt;p&gt;The premise sounds absurd: a permanently free cloud server with 4 ARM cores, 24 GB of RAM, 200 GB of storage, and 10 TB of monthly egress. Not a 12-month trial, not a $300-credit countdown — free, as in Oracle will provision it today and you will still not have received a bill five years from now. The catch is that there are several catches, and understanding all of them before you commit is the difference between a genuinely useful piece of free infrastructure and a recurring headache.&lt;/p&gt;</description>
    </item>
    <item>
      <title>oVirt: Enterprise KVM Management with Real Scheduling Policies</title>
      <link>/posts/ovirt-enterprise-kvm-scheduling/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ovirt-enterprise-kvm-scheduling/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;/posts/xcp-ng-and-xen-orchestra-xenserver-successor/&#34;&gt;XCP-ng post&lt;/a&gt; ended on the placement gap — XCP-ng schedules at the pool level, not with true DRS — and the &lt;a href=&#34;/posts/making-proxmox-cloud-like/&#34;&gt;Proxmox post&lt;/a&gt; was an entire essay about how Proxmox makes you name the node yourself. This series keeps circling the same dividing line: a cluster manager &lt;em&gt;runs&lt;/em&gt; your VMs, but a cloud platform &lt;em&gt;decides where they go&lt;/em&gt;. oVirt is the open-source platform that most directly answers that question. It has a real scheduler — filters, weights, and load-balancing policies you configure — plus affinity groups and labels, live migration driven by those policies, and the enterprise feature set you would expect from the upstream of a Red Hat product.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Polars: The DataFrame That Replaced pandas</title>
      <link>/posts/polars-dataframe/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/polars-dataframe/</guid>
      <description>&lt;p&gt;pandas is not slow because its authors made bad choices. It is slow because of the choices that made it useful in 2008: a mutable, row-oriented data model built on NumPy, a single-threaded execution model that predates multi-core as a first-class concern, and a Python object layer that the GIL can never fully relinquish. Those choices were correct for their era. By 2025 they are a structural liability, and no amount of optimization inside the existing architecture can fix them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Post-Quantum Cryptography in Practice</title>
      <link>/posts/post-quantum-cryptography-in-practice/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/post-quantum-cryptography-in-practice/</guid>
      <description>&lt;p&gt;The uncomfortable truth about post-quantum cryptography is that the migration is not a future problem — the threat to long-lived confidential data is present right now, and the standards you need to start deploying have been final since August 2024. The equally uncomfortable counter-truth is that the hype machine has dramatically overstated how urgent this is for most of the systems most infrastructure engineers actually run. The gap between &amp;ldquo;state actors are almost certainly harvesting encrypted traffic today&amp;rdquo; and &amp;ldquo;you need to replace your TLS certificates by next quarter&amp;rdquo; is wide, and it pays to understand exactly where your systems sit in that gap.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PowerShell for Administrators</title>
      <link>/posts/powershell-for-administrators/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/powershell-for-administrators/</guid>
      <description>&lt;p&gt;If you came up on bash, your first encounter with PowerShell probably felt like being handed a shell that is somehow both more verbose and more pedantic than the one you know — &lt;code&gt;Get-ChildItem&lt;/code&gt; where you wanted &lt;code&gt;ls&lt;/code&gt;, capital letters everywhere, and a help system that lectures you. The instinct is to alias your way back to comfort and treat PowerShell as a worse bash. That instinct is wrong, and it costs you the one thing PowerShell does that bash fundamentally cannot. This post is the onramp that respects what you already know: where your shell intuition transfers directly, where it actively misleads you, and what the single big idea is that makes PowerShell worth learning rather than tolerating.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Private Cloud Showdown: Picking the Right Platform</title>
      <link>/posts/private-cloud-showdown/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/private-cloud-showdown/</guid>
      <description>&lt;p&gt;This &lt;a href=&#34;/posts/private-cloud-on-your-own-hardware/&#34;&gt;private-cloud series&lt;/a&gt; opened with a promise: nine deep-dives, then a head-to-head that puts them all on one table and tells you which to actually run. This is that post. If you have read the others — &lt;a href=&#34;/posts/openstack-full-reference-cloud/&#34;&gt;OpenStack&lt;/a&gt;, &lt;a href=&#34;/posts/apache-cloudstack-underrated-workhorse/&#34;&gt;CloudStack&lt;/a&gt;, &lt;a href=&#34;/posts/opennebula-pragmatic-private-cloud/&#34;&gt;OpenNebula&lt;/a&gt;, &lt;a href=&#34;/posts/harvester-cloud-native-hci/&#34;&gt;Harvester&lt;/a&gt;, &lt;a href=&#34;/posts/incus-and-lxd-lightweight-cluster/&#34;&gt;Incus/LXD&lt;/a&gt;, &lt;a href=&#34;/posts/xcp-ng-and-xen-orchestra-xenserver-successor/&#34;&gt;XCP-ng&lt;/a&gt;, &lt;a href=&#34;/posts/ovirt-enterprise-kvm-scheduling/&#34;&gt;oVirt&lt;/a&gt;, &lt;a href=&#34;/posts/making-proxmox-cloud-like/&#34;&gt;cloud-like Proxmox&lt;/a&gt;, and &lt;a href=&#34;/posts/maas-bare-metal-as-a-service/&#34;&gt;MAAS&lt;/a&gt; — this is the synthesis. If you have not, this is the map that tells you which one to go read.&lt;/p&gt;&#xA;&lt;p&gt;The single most important thing to say up front is the thing the comparison blogs bury: &lt;strong&gt;the right answer is almost never the most powerful platform.&lt;/strong&gt; It is the smallest one that covers the capabilities you actually need. Most people asking &amp;ldquo;should I run OpenStack?&amp;rdquo; should run something else, and most of this post is an argument for matching the tool to the scale honestly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>QUIC and HTTP/3 Deep Dive</title>
      <link>/posts/quic-and-http3-deep-dive/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/quic-and-http3-deep-dive/</guid>
      <description>&lt;p&gt;HTTP/2 was supposed to fix the web. It delivered multiplexed streams over a single connection, eliminating the need to open six parallel TCP connections per origin, compressing headers with HPACK, and enabling server push. By every theoretical metric it was a step forward — and it was, right up until the moment the network got lossy. The dirty secret of HTTP/2 is that by collapsing all application streams onto one TCP connection, it traded one form of head-of-line blocking for a worse one that sits deeper in the stack and is invisible to the application. QUIC, standardized as RFC 9000 in May 2021, and HTTP/3, defined in RFC 9114, exist entirely to solve this problem. Understanding what the problem actually is — and what QUIC specifically does to fix it — is the prerequisite for making informed decisions about whether, when, and how to deploy it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RabbitMQ Deep Dive</title>
      <link>/posts/rabbitmq-deep-dive/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rabbitmq-deep-dive/</guid>
      <description>&lt;p&gt;Message queues are one of those categories where the beginner&amp;rsquo;s mental model — &amp;ldquo;something sends a message, something else receives it&amp;rdquo; — is accurate enough to get started and wrong enough to cause real production incidents. RabbitMQ has been the workhorse of that category for nearly two decades, and it rewards the engineer who actually understands its model. It also punishes the engineer who treats it as a black box: misconfigured acknowledgements cause silently lost work, wrong exchange types cause messages that vanish without trace, and classic mirrored queues — the old high-availability mechanism — were removed entirely in RabbitMQ 4.0, leaving teams that never migrated to quorum queues holding a single-replica system they thought was redundant.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ray: Distributed Python Without the Pain</title>
      <link>/posts/ray-distributed-python/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ray-distributed-python/</guid>
      <description>&lt;p&gt;Ray occupies a specific and increasingly important niche: it is the distributed runtime that lets you write ordinary Python and scale it to hundreds of GPUs and thousands of CPU cores without porting your code to a different execution model. That claim is not unique to Ray — Dask makes a version of it, and Spark has PySpark — but Ray backs it up with a scheduling architecture that handles heterogeneous hardware, stateful long-running processes, and fine-grained task parallelism in ways the others do not. In practice, this makes Ray the substrate under a surprising amount of modern LLM infrastructure: OpenAI uses it to coordinate ChatGPT training, vLLM uses its executor model for multi-GPU inference, and frameworks like OpenRLHF lean on it for distributed reinforcement learning from human feedback pipelines. Ray joined the Linux Foundation in September 2025, signaling that the project&amp;rsquo;s governance has matured beyond a single commercial backer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reverse Engineering with Ghidra</title>
      <link>/posts/reverse-engineering-with-ghidra/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/reverse-engineering-with-ghidra/</guid>
      <description>&lt;p&gt;When the NSA released Ghidra in March 2019, the most significant thing about it wasn&amp;rsquo;t that a government agency had open-sourced a tool — it was that they had open-sourced a &lt;em&gt;decompiler&lt;/em&gt;. A decompiler that actually worked, on real binaries, across a wide range of architectures, for free. Until that point, if you needed a decompiler you either paid Hex-Rays a five-figure license fee for IDA Pro, used Hex-Rays&amp;rsquo; cloud decompiler with all the attendant confidentiality concerns, or made do with the handful of open-source attempts that ranged from incomplete to frankly dangerous to rely on. Ghidra changed the economics of binary analysis for individual researchers, small security teams, and academia overnight.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rook: Ceph as a Kubernetes Operator</title>
      <link>/posts/rook-ceph-kubernetes-operator/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rook-ceph-kubernetes-operator/</guid>
      <description>&lt;p&gt;There is a version of Ceph that you install on bare metal, wire up by hand, and spend a non-trivial fraction of your life keeping running. That version is real, it is powerful, and if you want the unvarnished guide to it, the &lt;a href=&#34;/posts/standalone-ceph-without-proxmox/&#34;&gt;standalone-ceph-without-proxmox&lt;/a&gt; post covers it. This post is about a different bet: what happens when you stop treating Ceph as an external dependency and let a Kubernetes operator own the whole thing — deploying it, wiring it to storage classes, and handling day-2 operations through the same reconciliation loop that runs your application workloads.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Server-Driven UI with htmx and Alpine.js</title>
      <link>/posts/server-driven-ui-htmx-alpine/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/server-driven-ui-htmx-alpine/</guid>
      <description>&lt;p&gt;For a decade the default answer to &amp;ldquo;build an interactive web app&amp;rdquo; has been: stand up a single-page application (SPA) in React or similar, expose a JSON API, and serialize your UI state into JavaScript on the client. It works, and for genuinely app-like products it is the right call. But it imposes a heavy tax — a build pipeline, a client-side router, a state-management story, an API layer that exists only to feed the frontend, and two copies of your domain model (one in the backend, one in the client). For a backend engineer who just wants a server to render interactive HTML, that tax can feel absurd.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQL Server Quick Start and T-SQL Cheat Sheet</title>
      <link>/posts/sql-server-quickstart-tsql-cheatsheet/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sql-server-quickstart-tsql-cheatsheet/</guid>
      <description>&lt;p&gt;If you already speak SQL — PostgreSQL, MySQL, or anything ANSI-flavored — then Microsoft SQL Server is not a new language so much as a new dialect with its own accent, its own tooling, and a handful of opinions that will trip you up in the first hour. This post is the onramp: enough to connect, run queries, understand the engine&amp;rsquo;s quirks, and keep one tab open as a T-SQL reference. It assumes you know what a JOIN and an index are, and focuses on what is &lt;em&gt;different&lt;/em&gt; about SQL Server rather than re-teaching relational basics.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Browser as a Platform</title>
      <link>/posts/the-browser-as-a-platform/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/the-browser-as-a-platform/</guid>
      <description>&lt;p&gt;If you write backends, you already have a rich mental model of your runtime: processes, threads, the heap, the scheduler, system calls. The browser is &lt;em&gt;also&lt;/em&gt; a runtime — arguably a more complex one — but backend engineers often treat it as an opaque box that &amp;ldquo;renders HTML.&amp;rdquo; This post fills in that box. It is not a tutorial on writing frontend code; it is a tour of the &lt;em&gt;platform&lt;/em&gt; your code runs on, so that frontend performance, race conditions, and security behavior stop being surprising. If you understand the rendering pipeline, the event loop, and the security model, the rest of the frontend is detail.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Linux Window Manager Landscape</title>
      <link>/posts/linux-window-manager-landscape/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-window-manager-landscape/</guid>
      <description>&lt;p&gt;Most Linux documentation reaches for the same shorthand: a window manager manages your windows, a desktop environment is a window manager plus extras. That&amp;rsquo;s accurate but flattening. It hides the fundamental architectural difference that has cleaved the Linux desktop in two since Wayland became the default session on most major distributions — a difference that determines not just what software you run, but how display, compositing, input, and security interact at the kernel boundary. Understanding it properly changes how you evaluate every option in the WM space, from the well-worn i3 to the scrollable niri to the animations-first Hyprland.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Modern Frontend Build Pipeline</title>
      <link>/posts/modern-frontend-build-pipeline/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-frontend-build-pipeline/</guid>
      <description>&lt;p&gt;To a backend engineer, the frontend build pipeline can look like an inscrutable pile of config files, a &lt;code&gt;node_modules&lt;/code&gt; directory the size of a small moon, and a build step that fails for reasons no one fully understands. But underneath the churn of tool names there is a small set of genuinely necessary problems, each with a clear reason to exist. This post walks the pipeline from your source files to the bytes the browser runs, explaining &lt;em&gt;why&lt;/em&gt; each stage is there. Once you see the problems, the tools stop being magic and become obvious solutions — and you can reason about a broken build instead of pasting config from a search result.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The OWASP LLM Top 10 and Prompt Injection</title>
      <link>/posts/owasp-llm-top-10-prompt-injection/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/owasp-llm-top-10-prompt-injection/</guid>
      <description>&lt;p&gt;There is a particular kind of vulnerability that does not have a patch. You cannot sanitize your way out of it, you cannot escape the dangerous characters, and you cannot put a regex in front of it that closes the hole. The hole is the architecture. Prompt injection is that vulnerability, and it sits at the top of the OWASP Top 10 for Large Language Model Applications because, five years into the production-LLM era, nobody has a real fix — only mitigations, layered defenses, and a clear-eyed understanding of what you are exposing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ThinLinc: Linux Remote Desktops and VDI</title>
      <link>/posts/thinlinc-linux-remote-desktops-vdi/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/thinlinc-linux-remote-desktops-vdi/</guid>
      <description>&lt;p&gt;Linux remote desktop infrastructure has a long history of half-measures: plain VNC with no session brokering, X2Go that struggles with modern desktop environments, xrdp bolted awkwardly onto a protocol designed for Windows, and NoMachine that works brilliantly until you read the license. ThinLinc, built by the Swedish company Cendio, occupies an unusual and underappreciated position in this space. It is a full virtual desktop infrastructure (VDI) platform built entirely on open-source foundations — TigerVNC, SSH, and PAM — wrapped in a proprietary broker layer that handles session persistence, multi-server load balancing, and device redirection in a coherent way that none of the free alternatives manage out of the box. It is not glamorous software. It lacks GPU-accelerated display protocols, the free tier tops out at ten concurrent users, and it runs on a commercial licensing model beyond that cap. But for organizations that need reliable, multi-user, brokered Linux desktops without buying into a full VDI stack from Citrix or VMware, ThinLinc is the most operationally mature option available.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Time, Order, and CRDTs: Coordinating Without a Clock</title>
      <link>/posts/time-order-crdts/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/time-order-crdts/</guid>
      <description>&lt;p&gt;There is a seductive idea that distributed ordering is easy: just timestamp every event with the wall clock and sort. It does not work, and understanding &lt;em&gt;why&lt;/em&gt; it does not work is the gateway to a beautiful set of tools for ordering events and merging concurrent changes without any central coordinator. This final post in the distributed-systems fundamentals series is about &lt;strong&gt;time and order&lt;/strong&gt; — why physical clocks lie, how to reason about causality instead, the clever clock designs production databases actually use, and &lt;strong&gt;CRDTs&lt;/strong&gt;, the data structures that let independent replicas edit freely and always merge into the same answer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Trino: One Query Engine Over Everything</title>
      <link>/posts/trino-query-engine/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/trino-query-engine/</guid>
      <description>&lt;p&gt;The fundamental premise of a data warehouse is that you should move data into one place before you query it. Extract it, transform it, load it — and then run your analytics on the copy. That model made sense when data lived in one or two operational databases and the warehouse was simply a denormalized, indexed replica optimized for reads. It makes progressively less sense as your data landscape fractures: Parquet files on S3, Iceberg tables managed by a lakehouse catalog, &lt;a href=&#34;/posts/postgresql-for-developers/&#34;&gt;PostgreSQL&lt;/a&gt; transactional databases, &lt;a href=&#34;/posts/apache-kafka-deep-dive/&#34;&gt;Apache Kafka&lt;/a&gt; topics, MongoDB collections, and Elasticsearch indices — each owned by a different team, each updated on a different cadence. ETL-ing all of it into a warehouse is expensive in pipeline engineering, expensive in storage duplication, and introduces latency between the source and the place where analysts can actually query it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Velero: Backup and DR for Kubernetes</title>
      <link>/posts/velero-backup-and-dr-for-kubernetes/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/velero-backup-and-dr-for-kubernetes/</guid>
      <description>&lt;p&gt;A Kubernetes cluster is not a database backup. The etcd cluster holding your API objects can be snapshot at the control-plane level, but that gets you API resources — Deployments, ConfigMaps, Secrets — not the actual data sitting on your PersistentVolumes. Conversely, a snapshot of your cloud volumes gets you PV data but says nothing about the Deployments and Services that tell Kubernetes what to do with that data. A proper cluster backup needs both halves working together, and that coordination is exactly what Velero provides.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Web Performance Engineering</title>
      <link>/posts/web-performance-engineering/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/web-performance-engineering/</guid>
      <description>&lt;p&gt;Performance engineering on the backend is a discipline: you have SLOs, you measure percentiles from real traffic, you profile before optimizing, and you do not trust a single number from your laptop. Frontend performance deserves the exact same rigor, and this post applies that SRE mindset to the browser. The good news for a backend engineer is that the methodology transfers directly — measure at the 75th percentile from real users, find the bottleneck, fix the thing that actually moves the metric. What is new is &lt;em&gt;which&lt;/em&gt; metrics matter and &lt;em&gt;what&lt;/em&gt; moves them, and that is what we will cover.&lt;/p&gt;</description>
    </item>
    <item>
      <title>XCP-ng and Xen Orchestra: The XenServer Successor</title>
      <link>/posts/xcp-ng-and-xen-orchestra-xenserver-successor/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/xcp-ng-and-xen-orchestra-xenserver-successor/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;/posts/incus-and-lxd-lightweight-cluster/&#34;&gt;last post&lt;/a&gt; covered Incus and LXD — containers and KVM VMs under one excellent CLI — and the &lt;a href=&#34;/posts/apache-cloudstack-underrated-workhorse/&#34;&gt;posts before it&lt;/a&gt; stayed in KVM territory too. This one changes hypervisors entirely. XCP-ng is built on &lt;strong&gt;Xen&lt;/strong&gt;, not KVM, and it carries a specific lineage: it is the fully-open community successor to &lt;strong&gt;Citrix Hypervisor&lt;/strong&gt;, formerly &lt;strong&gt;XenServer&lt;/strong&gt; — the commercial Xen platform that a generation of enterprises ran, and that Citrix has steadily made less appealing through licensing changes and a narrowing free tier. If you are one of the many shops looking at a XenServer estate and an unwelcome Citrix invoice, XCP-ng is the landing spot designed for exactly your migration, and Xen Orchestra is the reason the landing is soft.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Your Steam Deck Is a Linux PC: Non-Gaming Uses</title>
      <link>/posts/steam-deck-is-a-linux-pc/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/steam-deck-is-a-linux-pc/</guid>
      <description>&lt;p&gt;The Steam Deck shipped as a gaming handheld. What Valve quietly put inside it is an AMD Zen 2 APU running a full x86-64 Linux distribution — SteamOS 3, built on an Arch Linux base — with KDE Plasma sitting one mode-switch away. Every unit that has ever left a warehouse is a capable portable Linux workstation by default, no modifications required. The problem is that most owners never leave Game Mode, and the ones who do often collide immediately with SteamOS&amp;rsquo;s immutable root filesystem and conclude, wrongly, that the Deck is too locked down to be useful.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ceph as Software-Defined Storage: Block, File, and Object Across Every Platform</title>
      <link>/posts/ceph-software-defined-storage/</link>
      <pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ceph-software-defined-storage/</guid>
      <description>&lt;p&gt;Most storage starts life as a physical thing: a disk, a RAID card, a NAS appliance, a SAN with a four-figure support contract. Software-defined storage (SDS) is the idea that the disk should be dumb and the intelligence should live in software running on commodity servers — replication, healing, placement, snapshots, and the access protocols all implemented in code you can read, on hardware you already own. Ceph is the reference implementation of that idea. It takes a pile of disks across a pile of machines and turns them into one self-healing cluster that speaks block, file, and object simultaneously.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Private Cloud on Your Own Hardware: Replicating AWS and Azure On-Prem</title>
      <link>/posts/private-cloud-on-your-own-hardware/</link>
      <pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/private-cloud-on-your-own-hardware/</guid>
      <description>&lt;p&gt;There is a particular feeling the first time you use a public cloud. You type a command, and ninety seconds later a virtual machine exists — with an IP address, a firewall, a disk, and an operating system — on hardware you will never see, chosen by software you will never meet. You did not pick the physical server. You did not rack anything. You asked for capacity and the cloud decided where to put it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI in the Terminal</title>
      <link>/posts/ai-in-the-terminal/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ai-in-the-terminal/</guid>
      <description>&lt;p&gt;There is a version of AI-assisted development that requires you to stop what you are doing, open a browser tab, paste some text, read a response, and then navigate back to your work. That version exists because it is the path of least resistance when you first sign up for any AI product. It also happens to be one of the least effective ways to use these tools, because it turns every question into a context switch and every integration into a manual process.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Audio and Video Setup for Remote Work and Content Creation</title>
      <link>/posts/home-office-audio-video/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-office-audio-video/</guid>
      <description>&lt;p&gt;There is a particular kind of embarrassment that only remote workers know: the moment when someone on a call says &amp;ldquo;you&amp;rsquo;re a little hard to hear&amp;rdquo; and you realize your carefully chosen background, your decent lighting, your framed bookshelves — none of it matters because the audio coming out of your laptop microphone sounds like you are calling from inside a bathroom tile factory. You have been broadcasting at people all day and half of them have been quietly suffering.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Audio for Live Broadcast</title>
      <link>/posts/live-broadcast-audio/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-broadcast-audio/</guid>
      <description>&lt;p&gt;This is the third post in a series on broadcasting meetings and church services. The first post laid out the signal-flow mental model — how a live signal is born at a source, moves through a chain of devices, and arrives at a viewer — and the second covered cameras and the switcher that ties them together: PTZOptics PTZ cameras feeding a Blackmagic ATEM. Both of those posts were, in a sense, about the part of the broadcast that people &lt;em&gt;see&lt;/em&gt;. This one is about the part they &lt;em&gt;hear&lt;/em&gt;, and it is the part almost everybody gets wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automating Your Life with n8n and AI</title>
      <link>/posts/automating-with-n8n-and-ai/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/automating-with-n8n-and-ai/</guid>
      <description>&lt;p&gt;There is a version of automation that looks impressive in a demo and breaks the moment you try to run it at scale. Then there is the version that you actually trust — the kind where you wake up on a Monday morning and your inbox has already been triaged, your morning briefing was assembled from two dozen RSS feeds and delivered to your phone at 6:45, and your GitHub notification queue has been filtered down to the three things you actually need to act on. Everything else got routed, labeled, digested, or quietly discarded while you were asleep.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a High-Productivity Home Office on Any Budget</title>
      <link>/posts/home-office-on-any-budget/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-office-on-any-budget/</guid>
      <description>&lt;p&gt;I have set up home offices in five different apartments and two houses over the past decade, at budgets ranging from &amp;ldquo;I found this chair on the curb&amp;rdquo; to &amp;ldquo;I just got a raise and I&amp;rsquo;m spending it on a sit-stand desk.&amp;rdquo; I have also watched dozens of colleagues and friends do this badly: spending $400 on a ring light and a desk plant before buying a keyboard, then complaining about wrist pain six months later. The money-wasting patterns are almost universal. This post is an attempt to give you a framework that prevents those mistakes, whether you have $200 or $5,000 to spend.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building an AI-Augmented Knowledge Work Workflow</title>
      <link>/posts/ai-augmented-knowledge-work/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ai-augmented-knowledge-work/</guid>
      <description>&lt;p&gt;After two-plus years of daily use, I have developed a clear-eyed view of where large language models actually help and where they create the illusion of help while quietly burning more of your time than they save. The honest answer is not that AI is good or bad for knowledge work. The honest answer is that it depends entirely on the task, and most people — including experienced practitioners — are poor at matching the tool to the task.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cable Management and Desk Hardware Setup</title>
      <link>/posts/home-office-cable-management/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-office-cable-management/</guid>
      <description>&lt;p&gt;There is a specific kind of dread that sets in when you look under your desk. A power strip with its cord doubled back on itself, three separate USB cables running from the same computer to the same side of the desk at slightly different angles, a monitor cable zip-tied to nothing, the charging cable for your phone hanging off the edge like it gave up. If you have a drawer under your desk, it is probably full of cables from hardware you stopped using two years ago. The mess is not because you are lazy or disorganized. It is because cable management without a plan always degenerates into cable management theater — you buy a few cable clips, stick them under the desk, feel like you accomplished something, and six months later the situation is exactly as bad as before.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Camera Operation and Directing Styles</title>
      <link>/posts/live-broadcast-camera-operation/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-broadcast-camera-operation/</guid>
      <description>&lt;p&gt;This is the sixth and final post in our series on broadcasting meetings and church services. Over the previous five installments we built a complete technical system from the ground up: the signal-flow mental model that prevents catastrophes, the cameras and the Blackmagic ATEM switcher that tie the angles together, the audio chain that delivers a clean broadcast mix, the software and encoding layer that dresses up and compresses the program feed, and the streaming and distribution layer that gets it to the people watching from home. If you have followed along, you now have a system that &lt;em&gt;works&lt;/em&gt;. Cameras are placed, the switcher cuts cleanly, the audio is embedded and synced, the encoder is dialed in, and the stream is live.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cameras and Switchers: PTZ, SDI, and the Blackmagic ATEM</title>
      <link>/posts/live-broadcast-cameras-switchers/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-broadcast-cameras-switchers/</guid>
      <description>&lt;p&gt;This is the second post in our series on broadcasting meetings and church services. In the first installment we covered the audio chain and the signal-flow fundamentals that make or break a stream before a single pixel of video shows up. Now we get to the part everyone actually sees: cameras and the switcher that ties them together.&lt;/p&gt;&#xA;&lt;p&gt;I have installed and operated multi-camera systems in a couple dozen sanctuaries, fellowship halls, and conference rooms over the years, ranging from a single fixed camera bolted to a rear wall to eight-camera rigs with a dedicated operator booth. The single most important thing I have learned is that a live video system for a house of worship or a recurring meeting is fundamentally a &lt;em&gt;staffing&lt;/em&gt; problem disguised as a gear problem. You can buy the best cameras in the world, but if you need three trained operators every Sunday and you only have one volunteer who showed up, the best cameras in the world will be pointed at the back of someone&amp;rsquo;s head. Almost every decision in this post comes back to that reality. Let&amp;rsquo;s start there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ClickHouse for Analytics Workloads</title>
      <link>/posts/clickhouse-for-analytics/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/clickhouse-for-analytics/</guid>
      <description>&lt;p&gt;ClickHouse is the fastest analytical database I have used in production. That sentence requires qualification: fastest for the workloads it was designed for — wide tables, aggregations over hundreds of millions of rows, time-series scans, high-cardinality GROUP BY operations — and genuinely terrible for everything else. The speed is not magic. It is the result of a coherent set of architectural decisions that trace back to one foundational choice: column-oriented storage. Understanding why that choice matters, and what trade-offs it forces, is the prerequisite for using ClickHouse well.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ergonomics Fundamentals for the Home Office</title>
      <link>/posts/ergonomics-for-the-home-office/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ergonomics-for-the-home-office/</guid>
      <description>&lt;p&gt;There is a particular kind of pain that creeps in so slowly you almost miss the onset. Not the sharp protest of a twisted ankle, but the slow accumulation of a thousand small insults to your joints, tendons, and postural muscles over months of sitting at a poorly arranged desk. By the time most people decide to investigate the cause of their chronic neck tension, their persistent wrist ache, or the low back stiffness that shows up every afternoon around three o&amp;rsquo;clock, the habits producing it have been running for years.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lighting Your Home Office for Focus and Video Calls</title>
      <link>/posts/home-office-lighting/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-office-lighting/</guid>
      <description>&lt;p&gt;Most people treat office lighting as an afterthought. You move into a room, screw in whatever bulbs came with the fixture, maybe add a desk lamp from a big-box store, and call it done. The overhead light works. You can see. Job complete.&lt;/p&gt;&#xA;&lt;p&gt;This is a mistake that compounds daily. Lighting shapes your cognitive state, alters your perception of time, determines how fatigued your eyes become over an eight-hour workday, and communicates something about your competence and attention to detail every time you appear on a video call. It operates mostly beneath conscious awareness, which is exactly what makes it dangerous to ignore. When you feel inexplicably drained at 3pm, when your eyes burn after a long session of reading, when a colleague mentions you look washed out on camera — lighting is often the culprit, and fixing it costs less effort and money than almost any other desk upgrade you could make.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Networking with ip, nftables, and tc</title>
      <link>/posts/linux-networking-ip-nftables-tc/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-networking-ip-nftables-tc/</guid>
      <description>&lt;p&gt;There is a class of Linux administrator who still reaches for &lt;code&gt;ifconfig&lt;/code&gt; out of muscle memory, types &lt;code&gt;netstat -tulnp&lt;/code&gt; without thinking, and has a collection of gnarly &lt;code&gt;iptables -A&lt;/code&gt; one-liners saved in a notes file from 2013. If that describes you, this post is not a lecture — it is a practical migration and upgrade guide. The old tools still work on many systems, but they are reading stale data, they are unmaintained, and in the case of &lt;code&gt;iptables&lt;/code&gt; they are being quietly replaced underneath you whether you notice or not. On a modern Debian 12 or Ubuntu 24.04 host, the &lt;code&gt;iptables&lt;/code&gt; binary you invoke is a compatibility shim that translates your rules into nftables behind the scenes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Performance Analysis</title>
      <link>/posts/linux-performance-analysis/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-performance-analysis/</guid>
      <description>&lt;p&gt;Performance analysis on Linux is one of those disciplines where the tools are abundant, the documentation is scattered, and the temptation to reach for the nearest command and start poking is nearly irresistible. That instinct is expensive. A production system under load is not the place to run random commands and hope for insight. What you need is a methodology — a way to systematically eliminate hypotheses and converge on a root cause before your incident window closes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Security Hardening Baseline</title>
      <link>/posts/linux-security-hardening-baseline/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-security-hardening-baseline/</guid>
      <description>&lt;p&gt;A default Linux installation is a study in competing priorities. The distribution maintainers have to make choices that work across a wide range of hardware, use cases, and skill levels. Security is on their list, but so is &amp;ldquo;works out of the box on a laptop bought at a retail store.&amp;rdquo; The result is a system configured for usability, not for running production workloads exposed to the internet.&lt;/p&gt;&#xA;&lt;p&gt;This is not a criticism — it is a design decision that puts the responsibility for hardening squarely on the operator. The question is what hardening actually means, what threat model it addresses, and which controls are worth the operational cost. That last part is where most hardening guides fail you: they hand you a checklist without explaining what breaks when you apply it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local LLMs with Ollama</title>
      <link>/posts/local-llms-with-ollama/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-llms-with-ollama/</guid>
      <description>&lt;p&gt;I run local LLMs every day. Not because they are better than GPT-5 or Claude Opus — they are not, not on the hard stuff — but because they are mine. They run in my homelab, on my hardware, in my network. When I ask them something sensitive, the tokens never leave the machine. When I want to spam a summarization pipeline with ten thousand documents, I am not watching an API bill climb. When I am on a plane, they still work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LVM and Linux Filesystem Comparison</title>
      <link>/posts/lvm-and-linux-filesystems/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/lvm-and-linux-filesystems/</guid>
      <description>&lt;p&gt;Storage on Linux is a deep subject that rewards careful study. The raw partition model that new users learn first — carve up a disk with &lt;code&gt;fdisk&lt;/code&gt;, format with &lt;code&gt;mkfs&lt;/code&gt;, mount it — works fine for a single machine with a single disk and a static workload. The moment your requirements become even slightly dynamic, that model starts working against you. You need more space on &lt;code&gt;/var/lib/docker&lt;/code&gt; but the partition is at 95% and the adjacent one is nearly empty. You need a consistent backup of a live database. You want to provision fifty virtual machines without pre-allocating fifty separate disk images. Partitions, as a concept, cannot help you here.&lt;/p&gt;</description>
    </item>
    <item>
      <title>macOS for Linux and Windows Switchers</title>
      <link>/posts/macos-for-switchers/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/macos-for-switchers/</guid>
      <description>&lt;p&gt;There is a specific kind of frustration that comes from switching to macOS after years on Linux or Windows. It is not the frustration of incompetence — you know how computers work. It is the frustration of a system that insists on doing familiar things in unfamiliar ways, without explanation, and with an air of certainty that its way is better. The maximize button does not maximize. The Ctrl key does not do what you expect. Cut-and-paste for files does not work the way you think. The file system layout looks wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>macOS Power User Tips and Hidden Features</title>
      <link>/posts/macos-power-user-tips/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/macos-power-user-tips/</guid>
      <description>&lt;p&gt;Most people learn a handful of macOS shortcuts, install a few apps from the App Store, and call it done. That is a perfectly functional setup, but it leaves enormous amounts of capability sitting idle. macOS is built on decades of thoughtful engineering, and the further you dig, the more you find: a scriptable automation framework that exposes nearly every system API to Lua, a command-line defaults system that unlocks hundreds of hidden behaviors, a Quick Look preview architecture that developers can extend with plugins, and a suite of built-in CLI tools that most users have never heard of.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Personal Knowledge Management with AI</title>
      <link>/posts/personal-knowledge-management-with-ai/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/personal-knowledge-management-with-ai/</guid>
      <description>&lt;p&gt;I have used roughly twelve personal knowledge management systems over the past decade. I have tried Notion, Roam, Logseq, Bear, Apple Notes, Confluence (personal instance, which is a special kind of madness), a custom SQLite-backed tagging system I built myself, plain text files in a Dropbox folder, DEVONthink, Evernote before it became a cautionary tale, Zettelkasten on index cards for about three weeks, and finally Obsidian. Along the way I built elaborate hierarchies, defined taxonomies, wrote personal ontologies, designed templates for seventeen different note types, and — this is the part that takes a while to admit — produced almost no useful output from any of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PgBouncer and PostgreSQL Connection Pooling</title>
      <link>/posts/pgbouncer-connection-pooling/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pgbouncer-connection-pooling/</guid>
      <description>&lt;p&gt;There is a specific kind of 3 a.m. that belongs exclusively to database engineers: the kind where your monitoring fires because &lt;code&gt;pg_stat_activity&lt;/code&gt; shows 487 connections and &lt;code&gt;max_connections&lt;/code&gt; is 500, your app servers are queuing requests, and you are watching &lt;code&gt;maxwait&lt;/code&gt; in PgBouncer climb past 30 seconds while trying not to wake your entire team. If you have not lived that experience, this post is your inoculation. If you have, this is the reference you wish you had beforehand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Planning a Live Broadcast: Signal Flow and System Design</title>
      <link>/posts/live-broadcast-signal-flow/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-broadcast-signal-flow/</guid>
      <description>&lt;p&gt;The first time I was responsible for a live broadcast that mattered, I learned everything I needed to know about live production in the four seconds after an HDMI cable worked itself loose from the back of a laptop. The stream went black. There was no second take, no &amp;ldquo;let me try that again,&amp;rdquo; no pause button. A few hundred people watching from home saw a black rectangle while I crawled under a table trying to find the connector by feel. That experience taught me more than any tutorial ever did, and it taught me the single most important truth about this work: in live production, the goal is not to be impressive. The goal is to not fail.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Internals and Tuning</title>
      <link>/posts/postgresql-internals-and-tuning/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/postgresql-internals-and-tuning/</guid>
      <description>&lt;p&gt;Most PostgreSQL performance problems I have seen — and I have seen a lot of them — trace back to the same root cause: the operator does not understand what the database is actually doing. They cargo-cult a Stack Overflow answer, set &lt;code&gt;shared_buffers&lt;/code&gt; to something plausible-sounding, and call it done. Then three months later they are debugging a table with 400 million dead tuples, a planner choosing sequential scans on indexed columns, and autovacuum perpetually behind. Understanding the internals is not optional if you want to run PostgreSQL reliably at scale. It is the entire job.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Replication and High Availability</title>
      <link>/posts/postgresql-replication-and-ha/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/postgresql-replication-and-ha/</guid>
      <description>&lt;p&gt;PostgreSQL&amp;rsquo;s replication story is one of the most mature in the open-source database world, but it has a way of humbling you. Streaming replication looks simple until you hit your first replication slot that quietly fills your disk overnight. Patroni looks like magic until your etcd cluster loses quorum at 2 AM and the leader lock expires. Logical replication looks like the perfect zero-downtime upgrade path until you discover that ALTER TABLE is not replicated and your schema migration broke the subscriber.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis Architecture and Persistence</title>
      <link>/posts/redis-architecture-and-persistence/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/redis-architecture-and-persistence/</guid>
      <description>&lt;p&gt;Redis is one of those systems that engineers tend to underestimate until they actually run it in production at scale. On the surface it looks like a fast key-value store — throw a string in, get it back later. In practice, Redis is a data structure server with persistence options, replication topologies, a cluster mode, eviction semantics, and diagnostic tooling sophisticated enough to serve as the backbone for rate limiters, session stores, leaderboards, pub/sub pipelines, and lightweight event streams. The gap between &amp;ldquo;I spun up Redis in Docker&amp;rdquo; and &amp;ldquo;I understand what Redis guarantees and when it will fail me&amp;rdquo; is significant, and this post intends to close most of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Software and Encoding: OBS, vMix, and the Mac Mini</title>
      <link>/posts/live-broadcast-software-encoding/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-broadcast-software-encoding/</guid>
      <description>&lt;p&gt;This is the fourth post in our series on broadcasting meetings and church services. So far we have built the signal flow, chosen and placed cameras behind a Blackmagic ATEM switcher, and tamed the audio chain. At the end of the last post the cameras were cut and the program output was leaving the switcher — and that is exactly where this one picks up. We have one clean program feed, and now we have to &lt;em&gt;do something&lt;/em&gt; with it: dress it up with graphics, encode it down to a bitrate the internet can carry, push it to a platform, and capture a pristine copy for the archive. This is the production-and-encoding layer, and it is where a surprising number of otherwise-good systems fall apart.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Streaming and Distribution</title>
      <link>/posts/live-broadcast-streaming-distribution/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/live-broadcast-streaming-distribution/</guid>
      <description>&lt;p&gt;This is the fifth post in our series on broadcasting meetings and church services. We have built the signal flow, placed cameras behind a Blackmagic ATEM switcher, tamed the audio chain, and chosen the production-and-encoding layer — OBS, vMix, or a hardware encoder running on a quiet Mac mini or a sealed appliance. At the end of the last post a single clean program feed had been dressed with graphics, encoded down to a sane bitrate, and was &lt;em&gt;about to leave the building&lt;/em&gt;. That arrow pointing at &amp;ldquo;YouTube / Facebook / RTMP-SRT&amp;rdquo; was doing a lot of quiet work. This post is about everything that happens after that arrow.&lt;/p&gt;</description>
    </item>
    <item>
      <title>systemd Deep Dive</title>
      <link>/posts/systemd-deep-dive/</link>
      <pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/systemd-deep-dive/</guid>
      <description>&lt;p&gt;systemd is everywhere. On Debian 12 (Bookworm) it ships as version 252. On Ubuntu 24.04 LTS (Noble Numbat) it is version 255.4. On Fedora 40 and later it is version 256 or higher. If you run Linux in production — on bare metal, in VMs, inside containers that use it — you are using systemd, and the gap between &amp;ldquo;I can start and stop services&amp;rdquo; and &amp;ldquo;I actually understand how this works&amp;rdquo; is larger than most people admit.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cloudflare Tunnels for Secure Homelab Exposure</title>
      <link>/posts/cloudflare-tunnels-homelab/</link>
      <pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cloudflare-tunnels-homelab/</guid>
      <description>&lt;p&gt;There is a certain ritual to traditional homelab exposure that every self-hoster eventually performs. You find your router&amp;rsquo;s port forwarding screen, you punch a hole for port 443, you pick a DDNS provider and install their client so your home IP stays registered under a hostname you can remember, you stand up Nginx or Caddy as a reverse proxy, and then you live with the consequences. Bot scanners find your IP within hours. The DDNS client occasionally fails silently and your service disappears. Your ISP changes your IP at the worst possible moment. A misconfiguration in your reverse proxy leaves a service exposed that you thought was internal-only. And you have told the entire internet, via DNS, where you live.&lt;/p&gt;</description>
    </item>
    <item>
      <title>WireGuard from Scratch</title>
      <link>/posts/wireguard-from-scratch/</link>
      <pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wireguard-from-scratch/</guid>
      <description>&lt;p&gt;There was a period in my career when &amp;ldquo;set up a VPN&amp;rdquo; meant three days of reading OpenVPN docs, debugging certificate chains, and eventually getting something working that nobody could explain to their manager. WireGuard did not invent the VPN, but it did something more valuable: it made the VPN auditable, fast, and boring in the best possible sense. This post covers WireGuard from the cryptographic primitives up through production deployment patterns — road warrior access, site-to-site routing, diagnostics, and an honest look at where it fits and where it does not.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Caddy as a Homelab Reverse Proxy</title>
      <link>/posts/caddy-homelab-reverse-proxy/</link>
      <pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/caddy-homelab-reverse-proxy/</guid>
      <description>&lt;p&gt;Every homelab eventually reaches the same inflection point. You have five services running on five different ports — Proxmox on 8006, Grafana on 3000, Immich on 2283, Forgejo on 3001, Home Assistant on 8123 — and you are tired of remembering which port maps to what. You want real domain names. You want HTTPS. You do not want to think about certificate management ever again.&lt;/p&gt;&#xA;&lt;p&gt;If you have been doing this for a while, your first instinct is probably Nginx. Nginx is battle-tested, fast, and well-documented. The problem is that Nginx has no concept of TLS certificate automation. You configure Nginx to serve HTTPS, then you separately run Certbot to get the certificate, then you write a renewal cron job, then you reload Nginx after renewal. Four separate systems, four places for things to break. Every six months your certs expire and you spend forty minutes debugging which piece of the chain failed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Grafana &#43; Prometheus Homelab Stack</title>
      <link>/posts/grafana-prometheus-homelab-stack/</link>
      <pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grafana-prometheus-homelab-stack/</guid>
      <description>&lt;p&gt;The first time your NAS fills up and silently drops writes, or your UPS battery dies the night before a power outage takes out your server, you learn the lesson: the homelab is not a toy environment, it just doesn&amp;rsquo;t have an on-call team. The machines don&amp;rsquo;t care that you&amp;rsquo;re asleep. The disk doesn&amp;rsquo;t warn you it&amp;rsquo;s 98% full before it starts corrupting files, and the switch port that went half-duplex three weeks ago isn&amp;rsquo;t going to file a ticket about the 40% packet loss you haven&amp;rsquo;t noticed yet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Home Assistant OS Deep Dive</title>
      <link>/posts/home-assistant-os-deep-dive/</link>
      <pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-assistant-os-deep-dive/</guid>
      <description>&lt;p&gt;I have been running Home Assistant continuously since the days when it was called hass.io and shipped as a single-board computer image with a handful of supported devices. That was before the Supervisor existed, before Z-Wave JS rewrote the book on Z-Wave reliability, and long before anyone thought a $20 ESP32 could serve as a local voice satellite. The platform has matured into something genuinely impressive — and genuinely complex. This post is the guide I wish existed when I started: a thorough, honest walkthrough of every major subsystem, covering what works well, what will bite you, and how to make deliberate architectural decisions rather than stumbling into a configuration you can never untangle.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: Network Automation and Programmability</title>
      <link>/posts/ccna-network-automation-programmability/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-network-automation-programmability/</guid>
      <description>&lt;p&gt;There is a section at the end of the CCNA 200-301 exam blueprint that has caused more than a few candidates to quietly panic. It is labeled &amp;ldquo;Automation and Programmability&amp;rdquo; and it sits there, weighted at roughly ten percent, asking you to explain REST APIs, compare data serialization formats, and describe what Cisco Catalyst Center actually does. For a candidate who spent the previous six months mastering subnetting, spanning tree, and OSPF LSA types, the sudden context switch to Python code and JSON payloads can feel disorienting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: Network Security Fundamentals</title>
      <link>/posts/ccna-network-security-fundamentals/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-network-security-fundamentals/</guid>
      <description>&lt;p&gt;Network security at the CCNA level is less about firewalls and more about discipline. The hardest problems to defend against are not the exotic zero-days — they are the attacks that exploit the fundamental trust assumptions baked into Ethernet and IP at Layer 2. ARP has no authentication. DHCP has no authentication. A switch, by default, will forward traffic to any MAC address it learns without question. An attacker who gets physical access to a switch port, or who plugs in a laptop in a conference room, immediately has a foothold that a perimeter firewall does nothing to stop.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: Wireless Networking Fundamentals</title>
      <link>/posts/ccna-wireless-networking-fundamentals/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-wireless-networking-fundamentals/</guid>
      <description>&lt;p&gt;Wireless networking is the section of the CCNA blueprint that catches candidates off-guard more than any other. The concepts look approachable on paper — radios, channels, access points — but the moment you dig into the physics, the security model, and the enterprise architecture, the complexity compounds quickly. Every layer of abstraction you peel back reveals another nuance that can make or break a real deployment. This guide covers the full CCNA wireless domain the way I wish it had been explained to me: as an integrated picture of RF physics, protocol evolution, security design, and enterprise architecture, rather than a disconnected set of facts to memorize.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cisco IOS Command Walkthroughs</title>
      <link>/posts/cisco-ios-command-walkthroughs/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cisco-ios-command-walkthroughs/</guid>
      <description>&lt;p&gt;Every Cisco IOS device speaks the same language, whether it is a decade-old 2811 still running branch voice or a Catalyst 9300 stack freshly racked in a new data center. That shared language is both IOS&amp;rsquo;s greatest strength and the reason so many engineers stop at the surface — they learn enough commands to get the job done, never quite understanding what the output is actually telling them. This guide is a desk reference for the engineer who wants to move past cargo-cult configuration and actually read the room.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Forgejo and Gitea: Self-Hosted Git</title>
      <link>/posts/forgejo-gitea-self-hosted-git/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/forgejo-gitea-self-hosted-git/</guid>
      <description>&lt;p&gt;Running your own Git server was, for years, either GitLab — which is excellent but heavy — or a bare Git daemon barely above &lt;code&gt;git init --bare&lt;/code&gt;. Gogs changed that in 2015 by shipping a single Go binary that was genuinely pleasant to use, and Gitea improved on it further. Today, Forgejo (a community fork of Gitea) sits at the top of that lineage: a self-contained Git platform with CI/CD, a container registry, organization permissions, webhooks, and experimental federation support, all in a binary that comfortably runs on a Raspberry Pi 4.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Immich: Self-Hosted Google Photos</title>
      <link>/posts/immich-self-hosted-photos/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/immich-self-hosted-photos/</guid>
      <description>&lt;p&gt;Google Photos is an extraordinary piece of software. It syncs automatically, indexes your entire life, surfaces memories you forgot you had, and lets you search for &amp;ldquo;birthday party 2019 outdoor&amp;rdquo; and find exactly what you mean. The catch is that you have handed Alphabet a complete record of everywhere you have been and everyone you have been with. For a growing subset of self-hosters, that trade is no longer acceptable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox VE in Production</title>
      <link>/posts/proxmox-ve-in-production/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-ve-in-production/</guid>
      <description>&lt;p&gt;Proxmox VE has become one of the most capable open-source virtualization platforms available, and after running a multi-node cluster in production for several years, I can say with confidence that it punches well above its weight class. This post is a comprehensive walkthrough of everything it takes to run Proxmox properly: cluster setup, storage backends, VM and container management, live migration, high availability with real fencing, PCIe passthrough, and backup with Proxmox Backup Server. The goal is not to rehash the official wiki. It&amp;rsquo;s to tell you what actually matters, what breaks, and how to think about the tradeoffs before you build something you have to maintain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tailscale for Homelab Networking</title>
      <link>/posts/tailscale-for-homelab-networking/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tailscale-for-homelab-networking/</guid>
      <description>&lt;p&gt;There is a particular kind of homelab frustration that every operator eventually hits. You have a NAS, a Proxmox cluster, a self-hosted Gitea instance, a monitoring stack, maybe a few Raspberry Pis scattered around — and you want to reach all of it from your laptop at a coffee shop or your phone on a cellular connection. The naive solution is to open ports. Port 22 for SSH, port 443 for the reverse proxy, maybe a non-standard port here or there to feel safer. You set up a DDNS record so your dynamic residential IP stays resolvable. You add &lt;code&gt;fail2ban&lt;/code&gt;. You tell yourself it&amp;rsquo;s fine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TrueNAS SCALE Deep Dive</title>
      <link>/posts/truenas-scale-deep-dive/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/truenas-scale-deep-dive/</guid>
      <description>&lt;p&gt;TrueNAS SCALE has matured from an experimental Linux-based challenger into a serious production NAS platform. If you run a homelab with meaningful storage requirements, or if you manage a small-to-medium storage environment at work and want something that does not cost a fortune in licensing, SCALE is worth understanding deeply. This post is not a &amp;ldquo;click here, click there&amp;rdquo; UI walkthrough. It is a systems-level treatment of how TrueNAS SCALE actually works — where ZFS fits in, how to design pools you will not regret, how to configure block and file protocols properly, and how to keep the whole thing running reliably over years.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: ACLs — Standard, Extended, and Named</title>
      <link>/posts/ccna-acls-standard-extended-named/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-acls-standard-extended-named/</guid>
      <description>&lt;p&gt;Access Control Lists are one of the most heavily tested topics on the CCNA exam, and for good reason: they touch almost every area of IOS operation. Routing, NAT, QoS classification, VTY access restrictions, route-map matching — all of these can reference an ACL. The underlying mechanism is always the same: a sequential list of permit and deny statements that the router evaluates top-to-bottom, stopping at the first match. Understanding that mechanism deeply, and knowing where and how to apply ACLs correctly, is the difference between an engineer who can read existing configs and one who can design and troubleshoot from scratch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: DHCP, DNS, and NTP on IOS</title>
      <link>/posts/ccna-dhcp-dns-ntp/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-dhcp-dns-ntp/</guid>
      <description>&lt;p&gt;Three services sit quietly underneath nearly every enterprise network and yet receive little attention until something breaks: DHCP hands out addresses so hosts can communicate at all, DNS translates the hostnames humans type into the IP addresses routers forward, and NTP keeps every clock on every device ticking in agreement so that log files mean something and security certificates stay valid. On Cisco IOS a single router can run all three simultaneously, serving hundreds of clients, relaying requests across subnet boundaries, and staying synchronised to internet time servers. This post walks through every piece of that picture — configuration syntax, verification output, common failure modes, and a complete multi-VLAN lab scenario — at the level of depth the CCNA exam actually expects.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: EIGRP Fundamentals</title>
      <link>/posts/ccna-eigrp-fundamentals/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-eigrp-fundamentals/</guid>
      <description>&lt;p&gt;Enhanced Interior Gateway Routing Protocol (EIGRP) sits in a unique position among routing protocols. It was developed by Cisco in the late 1980s as a proprietary replacement for IGRP, remained closed for decades, and was finally published as an informational RFC (RFC 7868) in 2016. It is classless, supports variable-length subnet masking, converges faster than almost any other IGP in common use, and is the only protocol in the CCNA exam scope that supports unequal-cost load balancing. For engineers preparing for CCNA, EIGRP is also the protocol most likely to generate confusion around its core convergence algorithm, the Diffusing Update Algorithm (DUAL), and specifically around the feasibility condition that separates a feasible successor from a route that merely looks attractive. This post covers all of it — from first principles through complete lab configurations with annotated IOS output.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: Ethernet and Switching Fundamentals</title>
      <link>/posts/ccna-ethernet-switching-fundamentals/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-ethernet-switching-fundamentals/</guid>
      <description>&lt;p&gt;Ethernet is the substrate of virtually every enterprise and datacenter network built in the last thirty years. It is so ubiquitous that most engineers take it for granted, pressing cables into ports and watching link lights go green without thinking much about what&amp;rsquo;s happening underneath. That&amp;rsquo;s fine until something breaks — a duplex mismatch quietly destroying throughput, a MAC flooding attack turning a switch into a hub, a flat Layer 2 domain dissolving under its own broadcast storm. The CCNA curriculum forces you to understand Ethernet properly, and the engineers who do understand it properly debug problems in minutes instead of hours.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: IPv4 Addressing and Subnetting</title>
      <link>/posts/ccna-ipv4-addressing-subnetting/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-ipv4-addressing-subnetting/</guid>
      <description>&lt;p&gt;Subnetting is the skill that separates engineers who passed the CCNA from engineers who understand networking. It shows up on every version of the exam, it shows up in every real network job, and it is the one topic where a methodical, practiced approach completely overcomes the time pressure. This post is long because subnetting deserves the full treatment: the math, the shortcuts, the worked examples, the exam traps, and the production context that makes it all make sense.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: IPv4 Routing Fundamentals</title>
      <link>/posts/ccna-ipv4-routing-fundamentals/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-ipv4-routing-fundamentals/</guid>
      <description>&lt;p&gt;Routing is the core function of a network layer device, and understanding exactly how a router makes its forwarding decision — which table it consults, which entry wins when multiple routes match, and how that entry resolves to a physical interface and next-hop MAC address — is the foundation on which every other networking topic rests. The CCNA exam tests this material relentlessly, and more importantly, the real world punishes misunderstanding it with silent packet drops, routing loops, and hours of troubleshooting. This post covers the entire IPv4 routing decision process from first principles through full Cisco IOS CLI verification, with worked multi-router scenarios and annotated command output throughout.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: NAT and PAT — Network Address Translation in Depth</title>
      <link>/posts/ccna-nat-and-pat/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-nat-and-pat/</guid>
      <description>&lt;p&gt;Network Address Translation is one of those topics that looks straightforward in a diagram and becomes genuinely confusing the moment you sit down with a real router and a packet capture. The terminology alone — inside local, inside global, outside local, outside global — trips up a significant number of CCNA candidates who have studied the concept but never internalized why those four terms exist and what problem each one solves. This post works through NAT and PAT from first principles: why they exist, how they actually work at the packet level, how to configure every variant in Cisco IOS, how to read the translation table, and how to diagnose failures systematically using the tools Cisco provides.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: OSPF Single-Area Configuration</title>
      <link>/posts/ccna-ospf-single-area/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-ospf-single-area/</guid>
      <description>&lt;p&gt;OSPF is the interior gateway protocol you will encounter everywhere — enterprise campuses, service provider cores, datacenter fabrics, CCNA exams, and every job interview that involves the word &amp;ldquo;routing.&amp;rdquo; It is also the protocol where most CCNA candidates first encounter the gap between memorizing facts and actually understanding how something works. You can recite the seven neighbor states without having any mental model of why those states exist, what triggers each transition, or what a stuck neighbor tells you about your network. This post attempts to close that gap.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: Spanning Tree Protocol — STP, RSTP, and Why Layer 2 Loops Are Catastrophic</title>
      <link>/posts/ccna-spanning-tree-protocol/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-spanning-tree-protocol/</guid>
      <description>&lt;p&gt;Spanning Tree Protocol is one of those topics where the exam question seems simple — &amp;ldquo;which port is blocking?&amp;rdquo; — but the underlying mechanics are subtle enough to bite you years into your career. STP was designed in 1985 by Radia Perlman at Digital Equipment Corporation and standardized as IEEE 802.1D in 1990. The problem it solves predates Ethernet as we know it today, and the solution it applies is elegant in a way that requires careful unpacking to fully appreciate. This guide covers everything from the fundamental loop problem through modern RSTP rapid convergence, with the Cisco IOS commands you need to configure and troubleshoot it in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: The OSI and TCP/IP Models in Practice</title>
      <link>/posts/ccna-osi-tcpip-models-in-practice/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-osi-tcpip-models-in-practice/</guid>
      <description>&lt;p&gt;Every networking course starts with the OSI model. Most of them present it as seven boxes on a slide, make you memorize &amp;ldquo;Please Do Not Throw Sausage Pizza Away,&amp;rdquo; and move on. That framing is a mistake. The layered model is not trivia — it is the mental framework that lets you decompose a connectivity failure into a specific, testable hypothesis. When a circuit is down and you are standing in a data center at 2 a.m., the question is never &amp;ldquo;which layer is broken?&amp;rdquo; in the abstract. The question is: &amp;ldquo;I have ruled out Layer 1 and Layer 2, so why is there no route in the table for this prefix?&amp;rdquo; The model gives you a structured way to stop thrashing and start eliminating.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: VLANs and Trunking — Complete Guide</title>
      <link>/posts/ccna-vlans-and-trunking/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-vlans-and-trunking/</guid>
      <description>&lt;p&gt;VLANs are one of those topics where the CCNA curriculum gives you just enough to pass an exam but not quite enough to reason clearly about production networks. The concepts layer on top of each other — access ports lead to trunks, trunks lead to DTP, DTP leads to VLAN hopping, and suddenly you are in a security conversation before you have finished the switching chapter. This guide works through all of it in sequence, with real IOS command output, honest notes on gotchas, and enough depth to make the knowledge stick.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CCNA: WAN Technologies and PPP</title>
      <link>/posts/ccna-wan-technologies-ppp/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ccna-wan-technologies-ppp/</guid>
      <description>&lt;p&gt;Wide-area networking is where networking gets expensive fast. The moment traffic leaves your building and crosses provider infrastructure, you are paying for bandwidth, paying for availability guarantees, and paying engineers to keep the whole thing from falling apart at 2 AM. For the CCNA, WAN technologies represent one of those topic areas where conceptual knowledge and hands-on CLI fluency are both expected. You need to understand why different link types exist, what happens at Layer 2 across a serial connection, how PPP authentication works at a protocol level, and how the industry has been steadily migrating away from dedicated circuits toward software-defined overlays.&lt;/p&gt;</description>
    </item>
    <item>
      <title>gVisor and Kata Containers: Sandboxed Container Runtimes for Multi-Tenant Kubernetes</title>
      <link>/posts/gvisor-kata-containers-sandboxed-runtimes/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gvisor-kata-containers-sandboxed-runtimes/</guid>
      <description>&lt;p&gt;Every container on a traditional Kubernetes node shares the host kernel. A busy CI/CD cluster running code from fifty different teams, or a FaaS platform executing end-user functions, operates with a thin namespace boundary separating each workload from every other workload — and from the host. When a researcher at SUSE disclosed three new runc container escapes in November 2025 (CVE-2025-31133, CVE-2025-52565, CVE-2025-52881), the question that cluster operators had been avoiding came back to the foreground: is namespace isolation actually enough?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Keycloak in Production: Realm Design, Federation, Kubernetes HA, and the Operational Reality of Running Your Own Identity Provider</title>
      <link>/posts/keycloak-in-production/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/keycloak-in-production/</guid>
      <description>&lt;p&gt;Running your own identity provider is one of those decisions that looks straightforward until the first time a misconfigured redirect URI causes an OAuth2 callback loop at 2 AM, or your LDAP sync job silently stops working and nobody notices until payroll can&amp;rsquo;t log in. Keycloak is remarkably capable — it handles OIDC, OAuth2, SAML 2.0, user federation, social login, MFA, passkeys, and multi-tenancy Organizations all in one open-source package backed by Red Hat. That capability comes with a configuration surface area that can swallow teams whole.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vault PKI Secrets Engine in Production: Intermediate CAs, cert-manager, and Short-Lived Certificates as a Security Primitive</title>
      <link>/posts/vault-pki-secrets-engine-production/</link>
      <pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vault-pki-secrets-engine-production/</guid>
      <description>&lt;p&gt;Modern service infrastructure lives or dies by its certificate hygiene. If you are still handing out one-year certificates with a vague promise to check the OCSP responder, this post is for you. We will walk through HashiCorp Vault&amp;rsquo;s PKI secrets engine — from the philosophical shift that short-lived certificates represent, through every &lt;code&gt;vault write&lt;/code&gt; command needed to stand up a production two-tier CA hierarchy, to cert-manager integration, Vault Agent sidecar patterns, SPIFFE identity, and the operational monitoring that keeps it all honest.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Network Policies in Depth: The Complete Guide</title>
      <link>/posts/kubernetes-network-policies-in-depth/</link>
      <pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-network-policies-in-depth/</guid>
      <description>&lt;p&gt;Network policies are one of the most important and most misunderstood security primitives in Kubernetes. They let you define exactly which pods can talk to which other pods — and to the outside world — at the network layer. Done right, they give you defense-in-depth that limits the blast radius of a compromised workload. Done wrong (or left unconfigured), every pod in your cluster can reach every other pod on every port.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NGINX Unit: The Application Server Nobody Talks About</title>
      <link>/posts/nginx-unit-application-server/</link>
      <pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nginx-unit-application-server/</guid>
      <description>&lt;p&gt;The standard Python web stack tutorial has not changed much in fifteen years: stand up NGINX, write a &lt;code&gt;uwsgi.ini&lt;/code&gt; or Gunicorn systemd unit, configure an &lt;code&gt;upstream&lt;/code&gt; block, reload the proxy. Something breaks, you SIGHUP NGINX, SIGHUP uWSGI, wonder which process manager restarted which worker, and eventually the site comes back up. Then you do it all again for the Node.js service, and again for the PHP legacy app.&lt;/p&gt;&#xA;&lt;p&gt;NGINX Unit was designed to make that entire ceremony disappear. It is a single binary that directly executes Python, Node.js, PHP, Go, Java, Ruby, Perl, and WebAssembly applications — no uWSGI, no Gunicorn, no pm2, no PHP-FPM needed. Its entire configuration lives in a JSON object you read and write over a Unix socket REST API. You &lt;code&gt;PUT&lt;/code&gt; a new config and your running applications reconfigure themselves in place, zero restarts, zero downtime, no SIGHUP.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SLO-as-Code with Sloth and Pyrra: Multi-Window Burn-Rate Alerts, Error Budget Policy, and Grafana Dashboards</title>
      <link>/posts/slo-sloth-pyrra-workflows/</link>
      <pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/slo-sloth-pyrra-workflows/</guid>
      <description>&lt;p&gt;Service Level Objectives are the most useful reliability tool most teams are still doing wrong. Not because the math is hard — it isn&amp;rsquo;t — but because the organizational and tooling setup around them usually breaks down before the SLOs ever make it into production alerting. This post covers the full stack: the conceptual foundations, the multi-window burn-rate alert math from the Google SRE Workbook, two mature SLO-as-code tools (Sloth v0.16 and Pyrra v0.10), complete worked YAML examples, Grafana integration, and the harder-to-automate conversation about what to actually do when the budget runs out.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AWS EKS Deep Dive: Managed Kubernetes on AWS</title>
      <link>/posts/eks-deep-dive/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/eks-deep-dive/</guid>
      <description>&lt;p&gt;Amazon EKS is AWS&amp;rsquo;s managed Kubernetes offering. AWS runs the control plane — multi-AZ etcd, API server, controller manager, scheduler — on infrastructure you never touch. You supply the nodes (or don&amp;rsquo;t, with Fargate). Simple premise; genuinely complex implementation once you hit production. This post covers everything that matters, including the decisions that come back to bite you at 2 a.m.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Current state as of May 2026:&lt;/strong&gt; EKS supports Kubernetes 1.33, 1.34, and 1.35 on standard support. Versions 1.30–1.32 are on extended support (additional cost). The default version for new clusters is 1.35. Karpenter v1.x (GA since August 2024, currently at ~v1.12) is stable. EKS Pod Identity reached GA in late 2023. EKS access entries reached GA in early 2024. AL2 AMIs were end-of-life November 2025 — if you&amp;rsquo;re still on AL2 nodes, that&amp;rsquo;s your first action item.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kafka Connect Deep Dive</title>
      <link>/posts/kafka-connect-deep-dive/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kafka-connect-deep-dive/</guid>
      <description>&lt;p&gt;Kafka Connect is the data integration layer of the Kafka ecosystem. It bridges the gap between Kafka and every other system you run — databases, object stores, search engines, data warehouses, SaaS APIs — using a framework of pluggable, scalable, fault-tolerant connectors. It looks deceptively simple in the docs: deploy a JAR, POST a JSON config, data flows. Then you hit production, and the questions start. Why did the connector pause? What is a replication slot and why is my Postgres disk filling up? How do I guarantee exactly-once delivery for a source connector? Why did schema evolution break my consumers at 2 AM?&lt;/p&gt;</description>
    </item>
    <item>
      <title>LocalStack: AWS Development Without the Cloud Bill</title>
      <link>/posts/localstack-aws-development-without-the-cloud-bill/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/localstack-aws-development-without-the-cloud-bill/</guid>
      <description>&lt;p&gt;Waiting on a real AWS environment to run integration tests is a tax on developer velocity. A five-second S3 operation becomes a minute of credential setup, cross-account IAM negotiation, and cleanup scripts that sometimes don&amp;rsquo;t run. LocalStack replaces the AWS endpoint with a single Docker container, turning &lt;code&gt;us-east-1&lt;/code&gt; into &lt;code&gt;localhost:4566&lt;/code&gt;. The pitch is simple; the reality is more nuanced — and in early 2026, the project underwent structural changes significant enough that documentation from a year ago is actively misleading. This post covers how LocalStack works today, what changed, and how to use it without building false confidence in code that will fail in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Open Policy Agent and Gatekeeper: Policy as Code for Kubernetes and Beyond</title>
      <link>/posts/opa-gatekeeper-policy-as-code/</link>
      <pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opa-gatekeeper-policy-as-code/</guid>
      <description>&lt;p&gt;Policy enforcement in distributed systems used to mean hand-rolled middleware, feature flags, and tribal knowledge baked into deployment scripts. Open Policy Agent (OPA) changed that by introducing a general-purpose, declarative policy engine that separates &lt;em&gt;what the policy says&lt;/em&gt; from &lt;em&gt;how it&amp;rsquo;s enforced&lt;/em&gt;. Gatekeeper brings OPA into Kubernetes as a production-grade admission controller. This post covers everything from Rego fundamentals to running conftest in CI, and then walks out beyond Kubernetes into Envoy, Terraform, and microservice authorization.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apache Pulsar vs Kafka: Architecture, Trade-offs, and When to Choose Each</title>
      <link>/posts/apache-pulsar-vs-kafka/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apache-pulsar-vs-kafka/</guid>
      <description>&lt;p&gt;Kafka is the default choice for event streaming. It has been in production since 2011, runs at extraordinary scale at companies like Netflix, LinkedIn, and Uber, and has a mature ecosystem of managed services, connectors, and stream processors that no other system can match. If you are picking a message broker today with no specific constraints, Kafka is the reasonable choice.&lt;/p&gt;&#xA;&lt;p&gt;Pulsar makes a different set of architectural bets. Its compute-storage separation, first-class multi-tenancy, and built-in geo-replication address real operational pain points that Kafka requires bolt-on solutions to solve. For specific workloads — multi-tenant SaaS platforms, globally distributed applications, and systems that need independent scaling of compute and storage — Pulsar is not just competitive with Kafka; it is architecturally superior.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AWS CDK Deep Dive</title>
      <link>/posts/aws-cdk-deep-dive/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aws-cdk-deep-dive/</guid>
      <description>&lt;p&gt;AWS CDK is an infrastructure-as-code framework that lets you define AWS resources using TypeScript, Python, Go, Java, or C#. The synthesized output is CloudFormation—CDK is a CloudFormation generator, not a replacement—but the authoring experience is fundamentally different. Instead of writing hundreds of lines of YAML, you instantiate constructs in code, use loops and conditions natively, extract shared patterns into reusable components, and write tests against the synthesized output.&lt;/p&gt;&#xA;&lt;p&gt;Whether CDK is the right choice depends heavily on your team, your existing tooling, and what you are building. This post works through the full CDK programming model, from the three construct levels through CDK Pipelines and testing, and ends with a direct comparison against Terraform that does not pull punches.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AWS EventBridge in Depth</title>
      <link>/posts/aws-eventbridge-in-depth/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aws-eventbridge-in-depth/</guid>
      <description>&lt;p&gt;EventBridge is AWS&amp;rsquo;s managed event bus, and it is one of those services that looks simple until you look closely—at which point you realize it has quietly become the connective tissue for a wide range of AWS architectures. It receives events from AWS services, custom applications, and SaaS partners; routes them to targets through pattern-matched rules; and, through its Pipes and Scheduler extensions, handles point-to-point integrations and scheduled invocations that previously required purpose-built infrastructure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AWS IAM: Permission Boundaries, SCPs, and Least Privilege at Scale</title>
      <link>/posts/aws-iam-permission-boundaries-scps-least-privilege/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aws-iam-permission-boundaries-scps-least-privilege/</guid>
      <description>&lt;p&gt;IAM is the most important security control in AWS and the one most consistently misconfigured. Not because AWS documentation is unclear—it is actually quite good—but because IAM operates at the intersection of several distinct policy types that interact through rules most engineers never fully internalize. Identity-based policies, resource-based policies, permission boundaries, Service Control Policies, and session policies each restrict access through a different mechanism, and their combination is not intuitive. Debugging &amp;ldquo;why can&amp;rsquo;t this role do X&amp;rdquo; frequently requires tracing through all five simultaneously.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AWS Networking Deep Dive: VPCs, Transit Gateway, and PrivateLink</title>
      <link>/posts/aws-networking-vpc-transit-gateway-privatelink/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aws-networking-vpc-transit-gateway-privatelink/</guid>
      <description>&lt;p&gt;AWS networking is the one infrastructure decision that is genuinely hard to change after the fact. You can resize EC2 instances, swap RDS engines, and refactor IAM policies with manageable effort. Changing your VPC CIDR range after you have deployed services, connected to on-premises networks, and peered with a dozen other VPCs is not impossible — it is painful enough that most teams just live with the suboptimal choice rather than fix it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AWS Systems Manager: Beyond Parameter Store</title>
      <link>/posts/aws-systems-manager-beyond-parameter-store/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/aws-systems-manager-beyond-parameter-store/</guid>
      <description>&lt;p&gt;Most engineers know AWS Systems Manager as the place where Parameter Store lives. That is an accurate but deeply incomplete picture. SSM is a fleet management platform with eight distinct capabilities, several of which eliminate entire categories of operational burden that teams carry by default. The bastion host. The SSH key rotation process. The ad-hoc patching script that runs as a one-off cron job. The configuration drift that accumulates on instances between deployments.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a Local RAG Pipeline: From Documents to Answers</title>
      <link>/posts/building-local-rag-pipeline-documents-to-answers/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/building-local-rag-pipeline-documents-to-answers/</guid>
      <description>&lt;p&gt;The premise of RAG is simple: you have documents, you have questions, and you want answers grounded in those specific documents rather than in whatever a large language model memorized during training. The LLM alone cannot do this reliably — it has no knowledge of your documents, and even if you fine-tuned it on them, the knowledge would be stale the moment a document changed. RAG solves this by retrieving relevant passages at query time and placing them in the model&amp;rsquo;s context window as evidence before asking for an answer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cloud Cost Engineering: FinOps Without the Buzzwords</title>
      <link>/posts/cloud-cost-engineering-finops-without-buzzwords/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cloud-cost-engineering-finops-without-buzzwords/</guid>
      <description>&lt;p&gt;Studies consistently find that 30–40% of cloud spend is wasted: overprovisioned instances nobody has resized, stopped EC2 instances accumulating EBS charges, NAT Gateways processing gigabytes of traffic that could route through free VPC endpoints, development environments running on nights and weekends, storage buckets with data nobody has accessed in three years. The tooling to find and fix this has improved significantly, but the tooling is not the hard part.&lt;/p&gt;&#xA;&lt;p&gt;The hard part is organizational. Cloud cost optimization requires someone with the authority to change things, the data to know what to change, and the processes to prevent the waste from accumulating again. Without all three, you run a cost review, make some changes, declare victory, and six months later the bill is back where it started.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cloud Database Trade-offs: RDS vs Aurora vs DynamoDB vs ElastiCache</title>
      <link>/posts/cloud-database-tradeoffs-rds-aurora-dynamodb-elasticache/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cloud-database-tradeoffs-rds-aurora-dynamodb-elasticache/</guid>
      <description>&lt;p&gt;The most consequential architectural decision in a typical cloud application is not which container orchestrator to use or how to structure the microservices—it is which database. The choice is largely irreversible: data migrations are expensive, query patterns calcify around the original data model, and the database&amp;rsquo;s characteristics (consistency model, scaling approach, query language) shape every layer of the application above it.&lt;/p&gt;&#xA;&lt;p&gt;AWS offers four distinct managed database products that cover most use cases: RDS for conventional relational workloads, Aurora for high-throughput relational workloads, DynamoDB for key-value and document access patterns at any scale, and ElastiCache for in-memory caching and data structures. Each has a different cost model, scaling story, operational profile, and failure mode.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Container Security in the Cloud: From Image to Runtime</title>
      <link>/posts/container-security-image-to-runtime/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/container-security-image-to-runtime/</guid>
      <description>&lt;p&gt;Container security is not a single control but a series of layers that address different phases of the container lifecycle: what goes into an image, whether that image is built from verified sources, how Kubernetes constrains what containers can do at runtime, what network traffic is permitted between pods, where secrets live and how they reach workloads, and what actually happens when a container behaves unexpectedly in production. Each layer independently catches a class of attacks; together they define a posture that is difficult to compromise end-to-end.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Crossplane: Kubernetes-Native Cloud Infrastructure</title>
      <link>/posts/crossplane-kubernetes-native-cloud-infrastructure/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/crossplane-kubernetes-native-cloud-infrastructure/</guid>
      <description>&lt;p&gt;Crossplane is a control plane framework that turns Kubernetes into a platform for provisioning and managing cloud infrastructure. Rather than running &lt;code&gt;terraform apply&lt;/code&gt; from a CI job, you push YAML to Kubernetes and Crossplane&amp;rsquo;s reconciliation loop ensures the real world matches what you declared. An EC2 instance, an RDS database, a GCS bucket—all of them become Kubernetes objects with standard &lt;code&gt;kubectl&lt;/code&gt; tooling, RBAC, and GitOps workflows.&lt;/p&gt;&#xA;&lt;p&gt;This is a compelling idea on paper and a genuinely useful pattern for platform teams building self-service infrastructure APIs. It is also an architecture with real operational costs, specific failure modes, and constraints that are not obvious until you have run it in production. This post covers the core model in depth, how to write Compositions, how authentication works, where Crossplane wins and loses against Terraform, and what production operation looks like before you commit to it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>etcd: The Brain of Kubernetes</title>
      <link>/posts/etcd-brain-of-kubernetes/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/etcd-brain-of-kubernetes/</guid>
      <description>&lt;p&gt;If you lose etcd, you lose the Kubernetes cluster. Not the running workloads—containers keep running on nodes after etcd goes down—but the cluster&amp;rsquo;s ability to know about itself, reconcile desired state, or take any action. The control plane is blind. No new pods can be scheduled, no service endpoints update, no admission webhooks fire, no secrets are accessible to new pods, and no &lt;code&gt;kubectl&lt;/code&gt; commands work. The cluster still runs; it just cannot think.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HAProxy Deep Dive: Load Balancing, ACLs, and SSL Termination at Scale</title>
      <link>/posts/haproxy-deep-dive-load-balancing-acls-ssl/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/haproxy-deep-dive-load-balancing-acls-ssl/</guid>
      <description>&lt;p&gt;HAProxy is not the flashiest piece of infrastructure in a modern stack. It does not have a slick web UI, a cloud-managed tier, or a Kubernetes operator maintained by a VC-backed startup. What it has is twenty years of production hardening, a configuration language precise enough to express nearly any routing requirement, and performance characteristics that routinely handle millions of requests per second on commodity hardware. Nginx, Traefik, and Envoy each have their place, but when you need a load balancer where behavior is completely predictable and the configuration is auditable line by line, HAProxy is the reference implementation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HashiCorp Packer: Golden AMIs and Immutable Infrastructure</title>
      <link>/posts/hashicorp-packer-golden-amis-immutable-infrastructure/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hashicorp-packer-golden-amis-immutable-infrastructure/</guid>
      <description>&lt;p&gt;Packer is a machine image factory. You describe a source, a sequence of configuration steps, and an artifact format, and Packer launches a temporary instance, applies your provisioners, snapshots the result, and terminates the instance. The output is a versioned, tested, immutable image that can be deployed identically across every environment—dev, staging, and production—without any configuration management running at boot time.&lt;/p&gt;&#xA;&lt;p&gt;The case for this approach, called immutable infrastructure, is straightforward. When you mutate running servers—applying patches, pushing config changes, deploying application code—every server develops a slightly different history. Some have a yum update from March, some from April. Some have a config flag that was set by hand one Saturday during an incident and never codified. This drift is invisible until it matters, at which point you have a fleet of snowflakes that behave differently under load, during failover, or after a reboot. The golden AMI pattern eliminates drift by making the image the unit of change. You never update a running server. You build a new image, validate it, and replace instances.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Incident Response Automation: Self-Healing Infrastructure with AWS, Ansible, and Observable Feedback Loops</title>
      <link>/posts/incident-response-automation/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/incident-response-automation/</guid>
      <description>&lt;p&gt;Incidents do not wait for business hours, and humans do not respond at machine speed. The gap between detection and containment — measured in minutes during a compromise — is where real damage happens. Automated incident response closes that gap, but it introduces its own failure mode: automation that makes things worse faster. This post covers the full stack: the runbook authoring model, the event routing layer, Lambda remediation patterns, Ansible for ad-hoc response, and the observability you need to trust any of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Karpenter: Kubernetes Node Autoscaling Done Right</title>
      <link>/posts/karpenter-kubernetes-node-autoscaling/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/karpenter-kubernetes-node-autoscaling/</guid>
      <description>&lt;p&gt;The Kubernetes cluster-autoscaler works by watching for unschedulable pods, finding a node group whose launch template would accommodate them, and incrementing that node group&amp;rsquo;s desired count. AWS then starts an EC2 instance from the group&amp;rsquo;s predefined launch template. When nodes are underutilized, the autoscaler drains and terminates them. This works, but it has a fundamental constraint: you must define your node groups in advance, each with a fixed instance type and configuration. Scaling up means picking which predefined box to add more of.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Debugging in Production</title>
      <link>/posts/kubernetes-debugging-in-production/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-debugging-in-production/</guid>
      <description>&lt;p&gt;Kubernetes debugging is not hard once you have a repeatable mental model. The problem is that most engineers learn it reactively — something breaks in production, they grep through logs for an hour, stumble on the answer, and move on without internalizing the pattern. The next incident feels just as novel.&lt;/p&gt;&#xA;&lt;p&gt;This post is an attempt to systematize the investigation. Every Kubernetes failure mode falls into one of six categories: the pod crashes immediately on startup, the pod gets OOMKilled, the pod never schedules, DNS resolution fails, network policies block traffic, or TLS certificates are expired or misconfigured. Each category has a canonical set of commands and a specific thing to look for. Once you know the flowchart, most incidents resolve in under ten minutes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Multi-Region Active-Active: What It Actually Takes</title>
      <link>/posts/multi-region-active-active-what-it-actually-takes/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/multi-region-active-active-what-it-actually-takes/</guid>
      <description>&lt;p&gt;&amp;ldquo;We need to be multi-region active-active.&amp;rdquo; That sentence gets spoken in architecture reviews and executive briefings with increasing frequency, usually accompanied by a diagram showing two AWS regions with symmetric arrows between them. It sounds correct—two regions, both serving traffic, neither a hot standby—and it maps cleanly onto the mental model of &amp;ldquo;more redundancy is always better.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;It is also, for the vast majority of systems, the wrong answer. Not because multi-region architectures are wrong in principle, but because the phrase &amp;ldquo;active-active&amp;rdquo; bundles together several distinct problems—latency optimization, disaster recovery, data consistency, and fault tolerance—that have different solutions with different cost and complexity profiles. When engineers reach for active-active as a blanket response to &amp;ldquo;we need to be more reliable,&amp;rdquo; they usually end up building a system that is more expensive, harder to operate, and no more reliable than a well-designed active-passive or active-warm topology.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenSearch in Production</title>
      <link>/posts/opensearch-in-production/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opensearch-in-production/</guid>
      <description>&lt;p&gt;OpenSearch is what happens when AWS needs a search engine it can ship as a managed service without worrying about license compatibility. When Elastic changed Elasticsearch to SSPL in January 2021, AWS forked 7.10.2 under Apache 2.0, renamed it OpenSearch, replaced Kibana with OpenSearch Dashboards, and has been maintaining it independently since. The fork is now over four years old, the project is governed by the OpenSearch Software Foundation under the Linux Foundation (not by AWS), and OpenSearch 3.0 shipped in April 2025 with Lucene 10 underneath and roughly 20% query performance improvements over 2.x.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenTelemetry in Practice: Tracing, Metrics, and Logs Without Vendor Lock-In</title>
      <link>/posts/opentelemetry-in-practice-tracing-metrics-logs/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opentelemetry-in-practice-tracing-metrics-logs/</guid>
      <description>&lt;p&gt;Observability stacks used to be a negotiation with a vendor. You picked Datadog or New Relic or Dynatrace and they owned your instrumentation, your data model, and your exit costs. OpenTelemetry changes the deal. It gives you a vendor-neutral SDK and wire protocol that any backend can consume, so the decision of where to store and query your telemetry is decoupled from the decision of how to produce it.&lt;/p&gt;&#xA;&lt;p&gt;That promise is real, but OpenTelemetry is a large project with a lot of moving parts, and the gap between &amp;ldquo;I installed the library&amp;rdquo; and &amp;ldquo;I have a working observability pipeline&amp;rdquo; is wider than the documentation implies. This post bridges that gap. It covers the data model, the SDK for Go and Python, the Collector as a pipeline, and the full wiring to Grafana Tempo, Prometheus, and Loki. It also covers the parts that bite you in production: cardinality, context propagation breakage, and collector sizing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Full-Text Search vs Elasticsearch: Where the Line Actually Is</title>
      <link>/posts/postgresql-full-text-search-vs-elasticsearch/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/postgresql-full-text-search-vs-elasticsearch/</guid>
      <description>&lt;p&gt;The instinct to reach for Elasticsearch the moment search requirements appear is understandable but often wrong. Elasticsearch is a capable system, but it is also a separate cluster to deploy, a consistency boundary to manage, a data synchronization problem to solve, and an operational burden to carry indefinitely. For a surprising range of workloads, PostgreSQL&amp;rsquo;s built-in full-text search is fast enough, expressive enough, and vastly simpler to operate.&lt;/p&gt;&#xA;&lt;p&gt;This post is about knowing where the line is. PostgreSQL FTS handles millions of documents well, offers phrase search, relevance ranking, field boosting, result snippets, and fuzzy matching through &lt;code&gt;pg_trgm&lt;/code&gt;. Elasticsearch adds faceted search, aggregations, autocomplete, multilingual analysis, and semantic vector search at a scale and sophistication that PostgreSQL cannot match. The question is whether your actual requirements cross that line — and most applications, at most stages of their life, do not.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox VE: The Comprehensive Guide</title>
      <link>/posts/proxmox-ve-comprehensive-guide/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-ve-comprehensive-guide/</guid>
      <description>&lt;p&gt;Proxmox VE sits in a rare category of software: it is genuinely enterprise-capable, fully open-source, and free to use without a subscription. VMware ESXi served this role for a decade, but its acquisition by Broadcom and subsequent licensing changes sent a significant fraction of the homelab and small-business market looking for an alternative. Proxmox was already the answer for many; it is now the answer for many more.&lt;/p&gt;&#xA;&lt;p&gt;What makes Proxmox worth understanding in depth is that it is not just a hypervisor. It is a converged platform that manages KVM virtual machines, LXC containers, ZFS or Ceph storage, software-defined networking, clustering, high availability, and backups from a single web interface and a coherent REST API. The learning curve is real — the defaults are not always obvious, and some decisions made at installation (storage layout, network bridge names) are painful to change later. Understanding the platform before you deploy saves significant time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust for Systems Engineers: A Practical Onramp</title>
      <link>/posts/rust-for-systems-engineers-practical-onramp/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rust-for-systems-engineers-practical-onramp/</guid>
      <description>&lt;p&gt;Most Rust introductions spend the first three chapters on memory safety theory and the borrow checker rules before you have written a single useful program. This is not that post. The ownership model is genuinely important and you will need to understand it, but the fastest path to that understanding is writing code that touches real problems — network services, CLI tools, system calls — and encountering the compiler&amp;rsquo;s feedback in context.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Serverless in Production: Lambda Patterns That Hold Up</title>
      <link>/posts/serverless-production-lambda-patterns/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/serverless-production-lambda-patterns/</guid>
      <description>&lt;p&gt;Serverless is a billing model as much as it is an architecture. AWS Lambda charges for execution time in 1-millisecond increments and for the number of invocations, with no charge when the function is idle. That model suits workloads with uneven, bursty, or low-volume traffic better than it suits anything that runs continuously at high throughput — where EC2 or containers become cheaper.&lt;/p&gt;&#xA;&lt;p&gt;But &amp;ldquo;Lambda is cheap and scales automatically&amp;rdquo; is where most teams stop thinking, and it is where most Lambda production problems originate. Cold starts affect user-facing latency more than benchmarks suggest. The concurrency model has hard edges that cause silent request drops. API Gateway adds cost and complexity that HTTP APIs partially address. Event-driven architectures built on SQS and SNS require careful handling of partial failures and poison messages. Step Functions are the right tool for coordinating multi-step workflows, but Standard vs Express Workflow is not an aesthetic choice.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Terraform at Scale: Modules, Remote State, and the Drift Problem</title>
      <link>/posts/terraform-at-scale-modules-remote-state-drift/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/terraform-at-scale-modules-remote-state-drift/</guid>
      <description>&lt;p&gt;Terraform is easy to start with and surprisingly hard to scale. A single &lt;code&gt;main.tf&lt;/code&gt; that creates a VPC and a few EC2 instances works fine on a laptop. Two engineers working on the same infrastructure, three environments (dev/staging/prod), twenty modules shared across five teams, and a CI/CD pipeline that needs to run &lt;code&gt;terraform apply&lt;/code&gt; without a human watching — that is a different problem. The tooling supports it, but the defaults get you there slowly and painfully.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ZFS for the Homelab: Storage That Doesn&#39;t Lie</title>
      <link>/posts/zfs-homelab-storage-that-doesnt-lie/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zfs-homelab-storage-that-doesnt-lie/</guid>
      <description>&lt;p&gt;Most filesystems trust the disks they write to. ZFS does not. It checksums every block, verifies the checksum on every read, and if the checksum fails it silently repairs the data from parity or a mirror — or it tells you clearly that the data is gone and you need a backup. This is a different design philosophy from ext4 or XFS, and it shows up in the operational experience in ways that are hard to appreciate until you have watched ZFS catch and correct a bit-rot event that would have silently returned corrupted data on any other filesystem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI Code Review Bots: Building One Engineers Don&#39;t Mute</title>
      <link>/posts/ai-code-review-bots-building-one-engineers-dont-mute/</link>
      <pubDate>Fri, 22 May 2026 19:00:00 +0000</pubDate>
      <guid>/posts/ai-code-review-bots-building-one-engineers-dont-mute/</guid>
      <description>&lt;p&gt;AI-assisted coding pushed PR volume up 29% year-over-year in 2025. The number of engineers available to review that code stayed roughly constant. This is the gap that AI code review bots are trying to fill — and the gap most of them make worse by flooding developers with noise until someone disables the bot and leaves a comment explaining why.&lt;/p&gt;&#xA;&lt;p&gt;The problem is not that LLMs are bad at code review. They are genuinely good at it: they find logic errors, flag missing error handling, catch common security mistakes, and explain what a piece of code does in a way that helps reviewers understand intent. The problem is that the easy implementation — send the diff to an LLM, post everything it says as PR comments — produces a signal-to-noise ratio that erodes trust faster than any bug it catches.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Computer Use and Browser Agents: How They Actually Work, What Breaks, and How to Run Them Safely</title>
      <link>/posts/computer-use-browser-agents-anthropic-browser-use/</link>
      <pubDate>Fri, 22 May 2026 18:00:00 +0000</pubDate>
      <guid>/posts/computer-use-browser-agents-anthropic-browser-use/</guid>
      <description>&lt;p&gt;There is a category of AI tooling that has been simultaneously overhyped and genuinely underestimated. The pitch — an AI that uses a computer like a human does, clicking buttons, filling forms, navigating UIs without any custom API integration — sounds like vaporware until you actually watch it work. Then it sounds transformative until it breaks in the fourth step of a five-step task and starts clicking random things for thirty seconds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Local Coding Agent Stack: Aider, Continue, Cline, and OpenHands</title>
      <link>/posts/local-coding-agent-stack-aider-continue-cline-openhands/</link>
      <pubDate>Fri, 22 May 2026 17:26:47 +0000</pubDate>
      <guid>/posts/local-coding-agent-stack-aider-continue-cline-openhands/</guid>
      <description>&lt;p&gt;The coding assistant market split cleanly in 2025. One side: polished, subscription-based products (Cursor, Windsurf, GitHub Copilot) that own your context window and charge per seat. The other side: open-source agents you wire to your own models — cloud APIs via your own keys, or weights running locally on your own hardware. The second category is where things get interesting for homelab operators and privacy-conscious engineering teams.&lt;/p&gt;&#xA;&lt;p&gt;This post is a field guide to the four tools that define the BYOK/local category: &lt;strong&gt;Aider&lt;/strong&gt;, &lt;strong&gt;Continue&lt;/strong&gt;, &lt;strong&gt;Cline&lt;/strong&gt;, and &lt;strong&gt;OpenHands&lt;/strong&gt;. It covers what each one actually is (architecture, not marketing copy), where each sits on the autonomy spectrum, how they perform with local models at the 32B–70B tier, and the honest trade-offs against Claude Code and Cursor for day-to-day use.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Azure Linux 4.0 and Azure Container Linux GA: Microsoft&#39;s Hardened OS for Cloud-Native and AI Workloads</title>
      <link>/posts/azure-linux-4-0-and-container-linux-ga/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/azure-linux-4-0-and-container-linux-ga/</guid>
      <description>&lt;p&gt;Microsoft has been building its own Linux distribution for longer than most people realise. What started as CBL-Mariner — an internal distribution used across Azure infrastructure — has matured through three major versions into a legitimately interesting distro with a clear design centre: minimal attack surface, supply chain integrity, tight Azure integration, and now a specific focus on AI workload performance. The announcements at Open Source Summit North America 2026 on May 18th brought Azure Linux 4.0 into public preview and pushed Azure Container Linux to general availability. Both are worth understanding before you decide what runs your next AKS node pool.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Constrained Generation: Outlines, JSON Mode, and Structured Output That Works</title>
      <link>/posts/constrained-generation-outlines-json-structured-output/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/constrained-generation-outlines-json-structured-output/</guid>
      <description>&lt;p&gt;Every LLM application eventually needs structured output. The agent that calls tools needs parseable JSON. The extraction pipeline needs consistent field names. The classification step needs one of exactly three strings. And every one of these applications, if built naively, eventually breaks in production on a malformed response that looked fine in development.&lt;/p&gt;&#xA;&lt;p&gt;There are two fundamentally different approaches to getting structured output from an LLM: constrain the generation at the token level so invalid output is physically impossible, or prompt the model to produce the right format and fix it afterward. The second approach—call it &amp;ldquo;JSON mode&amp;rdquo;—is how most teams start. It fails often enough to cause real problems, in ways that are difficult to catch in testing and painful to debug in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Custom Mechanical Keyboards: QMK, ZMK, Splits, and Macropads</title>
      <link>/posts/custom-mechanical-keyboards-qmk-zmk/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/custom-mechanical-keyboards-qmk-zmk/</guid>
      <description>&lt;p&gt;The keyboard is the primary interface between an engineer and the machine. Most engineers spend almost no time thinking about it, which is how they end up typing on the same membrane keyboard that shipped with the office PC in 2019. Custom mechanical keyboards are the rabbit hole that fixes this — and like most rabbit holes, it is deeper than it first appears.&lt;/p&gt;&#xA;&lt;p&gt;This is not a buying guide for off-the-shelf mechanical keyboards. It is a guide to the DIY ecosystem: why you might build rather than buy, how to choose switches, what a split keyboard is and why many engineers switch to one permanently, the practical difference between QMK and ZMK firmware, and how a well-configured macropad changes how you interact with your tools.&lt;/p&gt;</description>
    </item>
    <item>
      <title>eBPF for Observability: Writing Your First Program</title>
      <link>/posts/ebpf-observability-writing-your-first-program/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ebpf-observability-writing-your-first-program/</guid>
      <description>&lt;p&gt;For most of Linux&amp;rsquo;s history, instrumenting the kernel meant two bad choices: add printk statements and recompile, or use SystemTap/DTrace-style tools that required kernel modules with no safety guarantees and a good chance of crashing your machine if you got something wrong. Neither was something you did casually on a production box.&lt;/p&gt;&#xA;&lt;p&gt;eBPF changed that. It is a technology built into the Linux kernel — no modules, no recompilation — that lets you attach small, verified programs to hundreds of kernel and userspace hooks. The programs run at JIT-compiled native speed. The verifier statically checks them before they run and rejects anything that could crash the kernel or loop forever. You can attach a tracer to a live production system, collect the data you need, and detach without ever restarting a process or risking stability.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Edge AI Accelerators: Coral, Hailo, and Jetson Orin Nano Super Compared</title>
      <link>/posts/edge-ai-accelerators-coral-hailo-jetson/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/edge-ai-accelerators-coral-hailo-jetson/</guid>
      <description>&lt;p&gt;The case for edge AI accelerators is not about raw performance — a desktop GPU will always win that comparison. It is about the performance-per-watt and performance-per-dollar that only makes sense when you need inference to run continuously, on a device that cannot have a 200W GPU attached to it, or in a form factor where a PCIe slot doesn&amp;rsquo;t exist.&lt;/p&gt;&#xA;&lt;p&gt;A Coral USB accelerator doing object detection in a Frigate NVR build draws 2W and processes 400 frames per second. The same workload on a Raspberry Pi 5&amp;rsquo;s CPU takes 150ms per frame and pegs a core. A Jetson Orin Nano Super can run a quantized Llama 3.1 8B model at useful speeds at 25W in a board smaller than a paperback book. These are real capabilities that serve real homelab and embedded use cases — but only if you understand where the edges are.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ESP32 and MicroPython for the Homelab: Custom Sensors and Home Assistant Integrations from Scratch</title>
      <link>/posts/esp32-micropython-homelab/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/esp32-micropython-homelab/</guid>
      <description>&lt;p&gt;The ESP32 sits in an interesting position for software engineers. It is powerful enough to run a real Python interpreter, cheap enough to deploy a dozen of them around a house without agonising over the budget, and well-documented enough that you can go from zero to a working temperature sensor publishing to Home Assistant in an afternoon. But the hardware side is unfamiliar territory for most server-side or web engineers, and the ecosystem is fragmented enough to waste several afternoons picking the wrong chip, wrong toolchain, or wrong integration approach before you find the combination that actually works.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LiteLLM and Model Routing: The Proxy Pattern for Multi-Provider LLM Apps</title>
      <link>/posts/litellm-model-routing-proxy-pattern-multi-provider-llm/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/litellm-model-routing-proxy-pattern-multi-provider-llm/</guid>
      <description>&lt;p&gt;Every team that moves beyond a single LLM provider hits the same infrastructure problem. You started with OpenAI, then someone wants Claude for long-context tasks, another team spun up a local Ollama instance for privacy-sensitive work, and now your billing is spread across four dashboards, your codebase has four different client libraries, and rotating a compromised API key means touching seventeen files. The proxy pattern solves this. LiteLLM is the most widely adopted open-source implementation of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LLM Evals: Testing Your AI Application Like Real Software</title>
      <link>/posts/llm-evals-testing-ai-applications/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/llm-evals-testing-ai-applications/</guid>
      <description>&lt;p&gt;There is a version of AI application development where you vibe-check a new prompt in the playground, see it produce something reasonable, ship it, and hope for the best. Most teams start here. The problem is not that this is reckless — prompts are often genuinely hard to reason about statically — the problem is that there is no other mechanism in place. No automated check catches the regression when you upgrade the underlying model. No dashboard tells you that the summarisation quality dropped 15% after last Tuesday&amp;rsquo;s deployment. No CI job fails when a prompt change that improves the happy path silently breaks three edge cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MCP Deep Dive: Servers, Resources, and Tools</title>
      <link>/posts/mcp-deep-dive-servers-resources-tools/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mcp-deep-dive-servers-resources-tools/</guid>
      <description>&lt;p&gt;Before MCP, connecting an LLM application to external data sources and tools required building a bespoke integration for every combination of client and service. Claude needed a custom plugin for GitHub; a different plugin for Postgres; another for your internal knowledge base. Cursor needed its own implementations of the same integrations. Every tool vendor had to build for every client. The result was the classic N×M integration problem: N LLM clients times M external services, each pair requiring its own implementation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mini PC Deep Comparison: Beelink, Minisforum, Topton, and GMKtec for the Homelab</title>
      <link>/posts/mini-pc-homelab-comparison/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mini-pc-homelab-comparison/</guid>
      <description>&lt;p&gt;The mini PC has quietly displaced the repurposed desktop and the secondhand enterprise server as the default homelab node for most people. The reasoning is sound: a current-generation mini PC idles at 6–12W, fits in a hand, costs $100–300 depending on the tier, runs Proxmox or any Linux distribution without modification, and outperforms an old Xeon that draws 80W at idle on single-threaded workloads. For a homelab that runs VMs, containers, a NAS stack, or a small Kubernetes cluster without needing GPU compute, mini PCs are the practical choice.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mixture of Experts Internals: Routing, Expert Parallelism, and Load Balancing</title>
      <link>/posts/mixture-of-experts-internals/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mixture-of-experts-internals/</guid>
      <description>&lt;p&gt;Mixture of Experts is no longer a research curiosity. As of 2025, over 60% of open-source frontier model releases use MoE architecture, and every model at the top of the Artificial Analysis leaderboard — DeepSeek-R1, Kimi K2, Mistral Large 3 — is a MoE model. The architecture delivers GPT-4-class performance at a fraction of the inference compute cost: DeepSeek-V3 has 671 billion total parameters but activates only 37 billion per token during inference.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nix and NixOS: Reproducible Infrastructure from the Ground Up</title>
      <link>/posts/nix-nixos-reproducible-infrastructure/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nix-nixos-reproducible-infrastructure/</guid>
      <description>&lt;p&gt;Every few years something comes along that makes you question how you have been doing a familiar thing. For system configuration, that thing is Nix. Not because it is new — Nix the package manager dates to 2003, NixOS the operating system to 2006 — but because the ideas it embodies are finally reaching critical mass in production infra, homelab setups, and developer tooling. The ecosystem crossed a threshold in 2024-2025 where the documentation improved enough and the tooling stabilized enough that reaching for it is no longer an act of masochism.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Passkeys and WebAuthn in Practice: A Developer&#39;s Complete Guide</title>
      <link>/posts/passkeys-and-webauthn-in-practice/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/passkeys-and-webauthn-in-practice/</guid>
      <description>&lt;p&gt;Passwords are a solved problem in the sense that everyone agrees they are terrible and nobody has successfully replaced them at scale — until now. By mid-2026, Microsoft has auto-enabled passkeys for millions of accounts, 87% of enterprises report active passkey deployments, and browser support has stabilised across Chrome, Firefox, Safari, and Edge to the point where conditional UI is reliable. The technology is no longer experimental. If you are building authentication today and you are not implementing passkeys, you are choosing to build something you will need to replace.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PiKVM and JetKVM: Remote Console Access for Real Servers</title>
      <link>/posts/pikvm-jetkvm-remote-console/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pikvm-jetkvm-remote-console/</guid>
      <description>&lt;p&gt;The problem with managing physical servers remotely is that everything breaks at the worst possible time and at the OS level where your SSH session can&amp;rsquo;t reach. A kernel panic during a dist-upgrade, a BIOS misconfiguration that boots the machine into a PXE loop, a botched grub update that leaves you at a &lt;code&gt;grub&amp;gt;&lt;/code&gt; prompt — all of these require console access, which ordinarily means being physically in front of the machine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Quantization Deep Dive: GPTQ, AWQ, GGUF, AQLM, and MLX</title>
      <link>/posts/quantization-deep-dive-gptq-awq-gguf/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/quantization-deep-dive-gptq-awq-gguf/</guid>
      <description>&lt;p&gt;A 70B parameter model in BF16 weighs 140 GB. That is four A100s just to fit it in VRAM—before the KV cache. Quantization compresses model weights to lower bit-widths, trading a small amount of output quality for a large reduction in memory and a substantial improvement in inference speed. Done well, INT4 quantization shrinks the 70B to roughly 40 GB with perplexity degradation that is imperceptible in most tasks. Done poorly, it destroys reasoning ability and introduces subtle hallucination patterns that are harder to catch than obvious quality regressions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Self-Hosted Image Generation: Flux.1, SDXL, and ComfyUI Workflows</title>
      <link>/posts/self-hosted-image-generation-flux-sdxl-comfyui/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/self-hosted-image-generation-flux-sdxl-comfyui/</guid>
      <description>&lt;p&gt;Running image generation locally on your own GPU means zero per-image cost, no rate limits, no content policy friction, and the ability to fine-tune on your own data. The tooling has matured to the point where a capable homelab machine—an RTX 4080 or better—can generate Flux.1 images at comparable quality to commercial APIs, serve them through a proper HTTP interface, and run automated pipelines that would cost hundreds of dollars per month at API rates.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Semantic Caching for LLM Applications: Cutting Cost and Latency</title>
      <link>/posts/semantic-caching-llm-cost-latency/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/semantic-caching-llm-cost-latency/</guid>
      <description>&lt;p&gt;LLM API calls are expensive and slow. A GPT-4o call costs $0.005–0.015 per 1K tokens and returns results in 500–1500ms. For applications where many users ask semantically similar questions—customer support, FAQ chatbots, documentation assistants, internal knowledge bases—a large fraction of those calls are paying full price for answers already computed moments ago.&lt;/p&gt;&#xA;&lt;p&gt;Exact-match caching solves a small part of this. If a user asks &amp;ldquo;what is your return policy?&amp;rdquo; and another user asks the identical string, a simple key-value cache serves the second request instantly. But &amp;ldquo;what&amp;rsquo;s your return policy?&amp;rdquo;, &amp;ldquo;can I return items?&amp;rdquo;, &amp;ldquo;how do returns work?&amp;rdquo;, &amp;ldquo;do you accept returns?&amp;rdquo; are all the same question from a cost perspective—the cached answer is equally correct for all of them. An exact-match cache misses every paraphrase.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Speculative Decoding: Draft Models, EAGLE, and How to Actually Use It</title>
      <link>/posts/speculative-decoding-draft-models-eagle/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/speculative-decoding-draft-models-eagle/</guid>
      <description>&lt;p&gt;LLM inference is memory-bandwidth bound, not compute bound. The GPU&amp;rsquo;s tensor cores sit largely idle during autoregressive generation because each forward pass reads the full model weight matrix to produce a single token. A 70B model in BF16 occupies roughly 140 GB; generating one token requires streaming all 140 GB through the GPU&amp;rsquo;s high-bandwidth memory. With A100 SXM at ~2 TB/s, that caps token throughput at around 14 tokens/second per request before you account for the KV cache, attention, and other overhead. More memory bandwidth does not fundamentally solve the problem—it just shifts the ceiling.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tailscale and the Zero-Trust Home Network</title>
      <link>/posts/tailscale-zero-trust-home-network/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tailscale-zero-trust-home-network/</guid>
      <description>&lt;p&gt;The traditional answer to &amp;ldquo;I want to access my home network remotely&amp;rdquo; is a VPN server: install OpenVPN or WireGuard on a box with a public IP, open a firewall port, distribute certificates or keys to clients, and manage it forever. It works, but it requires a machine with a reachable public IP, manual key distribution, and ongoing maintenance. If you have two networks you want to connect, you do it again. If you add a team member who needs access, you generate keys by hand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Temporal and Workflow Orchestration: Durable Execution for Engineers Who&#39;ve Been Burned</title>
      <link>/posts/temporal-workflow-orchestration-durable-execution/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/temporal-workflow-orchestration-durable-execution/</guid>
      <description>&lt;p&gt;Every engineer who has built a multi-step distributed process has the same scar tissue. An order processing flow that touches five services. A user onboarding pipeline that sends emails, provisions accounts, and calls three external APIs. A background job that needs to run for two minutes, retry on failure, and report completion back to the original request. You bolt it together with a task queue, add retry logic, write state to a database to track progress, and ship it. Six months later a partial failure leaves a user half-onboarded. A network blip causes a payment to be charged twice because the idempotency logic had a race condition. A queue worker crashes mid-job and the job silently disappears.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Quiet Server Build: Acoustics, Cooling, and Vibration in a Homelab</title>
      <link>/posts/quiet-server-build/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/quiet-server-build/</guid>
      <description>&lt;p&gt;The homelab that lives in a spare room or a basement is easy to ignore acoustically. The homelab in a home office, a bedroom, or a living room space demands a different approach. Enterprise hardware — repurposed rack servers, used Dell PowerEdge or HPE ProLiant nodes — solves the thermal problem well but solves the acoustic problem very badly. A 1U server with stock fans running at even 50% speed is clearly audible from across a room. Running a rack of them in an occupied space means either ear protection or a soundproof closet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>vLLM vs SGLang vs TensorRT-LLM: Inference Engine Shootout 2026</title>
      <link>/posts/vllm-sglang-tensorrt-llm-inference-engine-shootout/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vllm-sglang-tensorrt-llm-inference-engine-shootout/</guid>
      <description>&lt;p&gt;If you are running your own LLM inference — on-premises, homelab, or rented bare metal — the inference engine you choose has a larger impact on throughput and latency than any configuration knob inside that engine. The wrong choice costs real money: a poorly matched engine on an H100 can leave 40-60% of available throughput on the floor. The right choice depends on your workload, your hardware commitment to NVIDIA, and how much operational complexity you are willing to absorb.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing a Kubernetes Operator: The Complete Pattern</title>
      <link>/posts/writing-kubernetes-operator-complete-pattern/</link>
      <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/writing-kubernetes-operator-complete-pattern/</guid>
      <description>&lt;p&gt;A Kubernetes operator is a controller that watches custom resources you define and takes action to make the cluster match their declared state. The idea is straightforward; the implementation has sharp edges if you do not know the patterns. Every production operator uses the same skeleton: a CRD that defines the resource shape, a controller with a reconciliation loop that observes and acts, finalizers for cleanup on deletion, status conditions for communicating state back to users, and RBAC rules that give the controller exactly the permissions it needs and nothing more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>.NET Framework 4.8 &#43; IIS &#43; SQL Server: A Modern Development and Deployment Workflow for Legacy Apps</title>
      <link>/posts/dotnet-framework-4-8-iis-development-workflow/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dotnet-framework-4-8-iis-development-workflow/</guid>
      <description>&lt;p&gt;Plenty of revenue-critical apps are still running on .NET Framework 4.8, IIS, and SQL Server. The stack is supported, well-understood, and not going anywhere — Microsoft has committed to .NET Framework 4.8 support for the lifetime of Windows Server it ships with, which puts the realistic end-of-life past 2032. The problem isn&amp;rsquo;t that the stack is dying. The problem is that the tooling around it has aged unevenly, and the modern developer-experience patterns we expect from .NET 8 or Node.js apps don&amp;rsquo;t translate directly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hermes Agent: Setup, Local Models, and How It Compares to OpenClaw</title>
      <link>/posts/hermes-agent-setup-and-comparison/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hermes-agent-setup-and-comparison/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;../openclaw-self-hosted-ai-agents/&#34;&gt;OpenClaw&lt;/a&gt; defined what a self-hosted, persistent AI agent looks like when it ran the table in January and February. But the agent space moves fast, and in the three months since, a quieter project from Nous Research has been steadily eating into that mindshare: &lt;strong&gt;Hermes Agent&lt;/strong&gt;. Released in February 2026, it hit 95,600 GitHub stars in seven weeks — faster than LangChain and AutoGen combined — and it has a few design decisions that make it meaningfully different from OpenClaw, particularly for anyone who wants to run agents on local models.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes for the Homelab: K3s from Scratch to Production</title>
      <link>/posts/kubernetes-for-homelab/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-for-homelab/</guid>
      <description>&lt;p&gt;Running Kubernetes at home used to be a punishment. You stood up three Raspberry Pis with kubeadm, fought with cgroups for a weekend, and ended up with a cluster that ate more RAM than the workloads it was supposed to host. K3s changed the calculus: a single 70 MB binary, sane defaults, and a cluster that runs comfortably on a Mini PC with 8 GB of RAM. In 2026 it is the default answer for &amp;ldquo;I want real Kubernetes at home without renting a datacenter.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Llama 4 and Gemma 4: The 2026 Self-Hosted Model Landscape</title>
      <link>/posts/llama-4-and-gemma-4-self-hosting/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/llama-4-and-gemma-4-self-hosting/</guid>
      <description>&lt;p&gt;The last six weeks have been the busiest stretch of open-weight model releases since Llama 2 landed. Meta shipped the Llama 4 herd — Scout and Maverick — both natively multimodal mixture-of-experts models with context windows that are, in Scout&amp;rsquo;s case, frankly absurd. Google followed with four Gemma 4 variants, all under Apache 2.0, ranging from a 2B effective-parameter model designed for laptops up to a 31B dense model that holds its own against vastly larger closed models.&lt;/p&gt;</description>
    </item>
    <item>
      <title>3D Printing for Your Homelab</title>
      <link>/posts/3d-printing-for-your-homelab/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/3d-printing-for-your-homelab/</guid>
      <description>&lt;p&gt;A homelab eventually outgrows its furniture. A shelf covered in Raspberry Pis, a NUC leaning against a router, a USB hub zip-tied to the underside of a desk — functional, but every move risks dislodging something, and nothing is labeled or serviceable. A 3D printer is the single homelab accessory that transforms this from perpetually-messy to deliberately-organized, at the cost of a roll of filament.&lt;/p&gt;&#xA;&lt;p&gt;This post is a practical catalog of what&amp;rsquo;s worth printing for a homelab, which designs are actually good (from Thingiverse, Printables, MakerWorld), and where the limits are — places where a printed part is a bad idea even when it &lt;em&gt;is&lt;/em&gt; possible.&lt;/p&gt;</description>
    </item>
    <item>
      <title>3D Printing Safety at Home: VOCs, Particles, Fire, and Resin</title>
      <link>/posts/3d-printing-safety-at-home/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/3d-printing-safety-at-home/</guid>
      <description>&lt;p&gt;3D printing is generally safe. That sentence is true. It&amp;rsquo;s also incomplete, because safety depends on what you&amp;rsquo;re printing, where, and for how long — and the wrong answers to those questions can turn a benign hobby into a genuine health risk or a house fire.&lt;/p&gt;&#xA;&lt;p&gt;This post covers the safety considerations that actually matter for home 3D printing in 2026. Not an exhaustive OSHA-style reference, but a practical guide: what the real risks are, how big they actually are (with numbers where possible), what&amp;rsquo;s hype versus what&amp;rsquo;s substantiated, and the specific mitigations that make the most difference. By the end you should know what a safe setup looks like for your situation and what to change if yours isn&amp;rsquo;t.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a Small Print Farm: From One Printer to Five Without Losing Your Mind</title>
      <link>/posts/building-a-small-print-farm/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/building-a-small-print-farm/</guid>
      <description>&lt;p&gt;A &amp;ldquo;print farm&amp;rdquo; sounds more impressive than it usually is. The typical version is not a warehouse of industrial machines; it&amp;rsquo;s three to five consumer printers in a garage, basement, or spare room, running simultaneously to make more prints than a single printer could. That scale is where the interesting problems live: you can&amp;rsquo;t watch every printer, you can&amp;rsquo;t manually schedule every job, and a single failure mode across multiple machines can cost real money and real hours.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CAD for 3D Printing: Fusion 360, FreeCAD, Onshape, Plasticity Compared</title>
      <link>/posts/cad-for-3d-printing/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cad-for-3d-printing/</guid>
      <description>&lt;p&gt;Most people who start 3D printing download existing models. Thingiverse, MakerWorld, Printables, Cults3D — there&amp;rsquo;s a lifetime of free files to print. But eventually you want something that doesn&amp;rsquo;t exist: a specific bracket to fit a specific shelf, a custom phone stand with your exact angle preference, a replacement knob for an obscure appliance. That&amp;rsquo;s where CAD comes in, and that&amp;rsquo;s where a lot of hobbyists stall out.&lt;/p&gt;&#xA;&lt;p&gt;The problem isn&amp;rsquo;t that CAD is impossibly hard. The problem is that the CAD world was built for professionals, not hobbyists — and navigating the software landscape is almost more confusing than learning the software itself. Fusion 360, FreeCAD, Onshape, SolidWorks, Creo, Rhino, Blender, Plasticity, Tinkercad, OpenSCAD — all of these technically do &amp;ldquo;CAD,&amp;rdquo; and they all work very differently.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FDM vs Resin Explained: How Each Actually Works and Which One You Want</title>
      <link>/posts/fdm-vs-resin-explained/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fdm-vs-resin-explained/</guid>
      <description>&lt;p&gt;Walk into any 3D printing forum and you&amp;rsquo;ll find the same tribal argument: FDM people telling resin people their parts are weak and their hobby is a hazmat situation, and resin people telling FDM people their prints look like they were cut out of a sidewalk. Both sides are partly right, which is what makes the argument boring and the underlying question — &lt;em&gt;which technology should I buy?&lt;/em&gt; — genuinely interesting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Filament Types Demystified: PLA, PETG, ABS, TPU, Nylon, and the Composites</title>
      <link>/posts/filament-types-demystified/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/filament-types-demystified/</guid>
      <description>&lt;p&gt;A new 3D printing hobbyist in 2026 faces a filament catalog that would have been unthinkable in 2018. PLA in 200 colors and blends. PETG in silk, matte, translucent, glow-in-the-dark. ABS and ASA for heat resistance. TPU in four different shore hardnesses. Nylon in a dozen variants, with and without carbon fiber or glass fiber reinforcement. Polycarbonate. Wood-filled, metal-filled, ceramic-filled. Dissolvable supports. Annealable PLAs marketed as engineering-grade. Specialty blends that don&amp;rsquo;t fit any existing category.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Functional 3D Printing Design Rules</title>
      <link>/posts/functional-3d-printing-design-rules/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/functional-3d-printing-design-rules/</guid>
      <description>&lt;p&gt;A 3D-printed part is not the same thing as an injection-molded part that happens to be made on a printer. The process is directional — each layer bonds to the one below in a way that is not as strong as the solid material bonded within a single layer. This single fact controls almost every good design decision for functional printing.&lt;/p&gt;&#xA;&lt;p&gt;This post is a set of rules that come up repeatedly when designing parts that have to actually &lt;em&gt;work&lt;/em&gt; — carry loads, clip together, thread, flex, fit — rather than just look like the CAD model. It assumes FDM; resin rules are mostly different and are called out where they matter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ghostty and WezTerm as IDEs: Leaving VS Code&#39;s Integrated Terminal Behind</title>
      <link>/posts/ghostty-wezterm-as-ides/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ghostty-wezterm-as-ides/</guid>
      <description>&lt;p&gt;Ask a developer what their &amp;ldquo;IDE&amp;rdquo; is, and you&amp;rsquo;ll get two kinds of answer. The first is a product name: VS Code, IntelliJ, Cursor, Zed, Neovim with an IDE layer bolted on. The second is a workflow: &amp;ldquo;my editor plus a terminal plus a bunch of splits.&amp;rdquo; For a growing number of developers in 2026, the answer is drifting toward the second form — and the terminal emulator has become the host application, not a pane inside the editor.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Klipper vs Marlin: Why Serious 3D Printing Moved to the Raspberry Pi</title>
      <link>/posts/klipper-vs-marlin/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/klipper-vs-marlin/</guid>
      <description>&lt;p&gt;Every consumer 3D printer runs firmware on a microcontroller. For most of the 2010s and early 2020s, that firmware was &lt;strong&gt;Marlin&lt;/strong&gt; — the open-source, C++ codebase that grew out of the RepRap community and ran on AVR 8-bit chips, then on faster 32-bit STM32s as printers modernized. Marlin is still what ships on most Creality, Anycubic, and Elegoo FDM machines today. It works. It&amp;rsquo;s mature. It&amp;rsquo;s reliable.&lt;/p&gt;&#xA;&lt;p&gt;And yet the serious hobbyist community has mostly moved to &lt;strong&gt;Klipper&lt;/strong&gt; — a newer firmware that splits the stack, runs the heavy computation on a Raspberry Pi (or similar SBC) instead of the printer&amp;rsquo;s MCU, and communicates with a thin firmware layer on the microcontroller. The switch has real benefits (input shaping, pressure advance done right, smoother motion at high speeds) and real tradeoffs (more hardware, more setup, one more thing that can fail).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Multi-Material and Multi-Color Printing: What AMS, MMU3, and IDEX Actually Do</title>
      <link>/posts/multi-material-multi-color-printing/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/multi-material-multi-color-printing/</guid>
      <description>&lt;p&gt;Watch any Bambu Lab marketing video and you&amp;rsquo;ll see the same shot: a printer with a box of four filaments next to it, calmly producing a print with sharp color transitions between regions. No operator swapping spools mid-print, no manual intervention. The marketing promise is simple: multi-color, multi-material prints come out effortlessly.&lt;/p&gt;&#xA;&lt;p&gt;The reality is more nuanced. Multi-material printing is genuinely a revolution for certain use cases — and a time-and-filament sink for others. Between AMS, MMU3, IDEX, and the recently-released X2D with its dual-nozzle architecture, the technology landscape in 2026 has matured into something worth understanding deeply before spending the money.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OrcaSlicer Deep Dive: Calibration, Profiles, and the Settings That Matter</title>
      <link>/posts/orca-slicer-deep-dive/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/orca-slicer-deep-dive/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve used 3D printers in the last few years, you&amp;rsquo;ve probably used Bambu Studio or PrusaSlicer — the two slicers that dominate the consumer market. OrcaSlicer is the quieter third option that has become the power user&amp;rsquo;s choice in 2026. It&amp;rsquo;s a fork of Bambu Studio, which is itself a fork of PrusaSlicer, which is itself a fork of Slic3r. Four generations of inheritance, and the result is a tool that has &lt;strong&gt;most of Bambu Studio&amp;rsquo;s UI polish plus PrusaSlicer&amp;rsquo;s broader printer support plus its own purpose-built calibration tooling&lt;/strong&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Post-Processing Prints That Look Great</title>
      <link>/posts/post-processing-prints-that-look-great/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/post-processing-prints-that-look-great/</guid>
      <description>&lt;p&gt;Most 3D prints look like 3D prints. Layer lines visible, seams where the slicer started each layer, a faintly rough top surface, sharp corners slightly rounded. These are fine for prototypes, functional parts, and most of what comes off a hobby printer. But when you want a print to pass as &amp;ldquo;not 3D printed&amp;rdquo; — a case for a presentation, a cosplay prop, a model, a gift — finishing is what gets you there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Printing with Engineering Filaments</title>
      <link>/posts/printing-with-engineering-filaments/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/printing-with-engineering-filaments/</guid>
      <description>&lt;p&gt;PLA is friendly. It sticks to anything, prints at 210°C, dimensionally stable, forgiving of bad first layers, cheap. It also softens in a hot car, snaps under mild fatigue, and yellows in UV. For functional parts — brackets that live in an engine bay, outdoor enclosures, drone arms, tool handles, fixtures that see real load — PLA eventually disappoints you.&lt;/p&gt;&#xA;&lt;p&gt;Engineering filaments exist to solve those problems. They can absolutely do things PLA cannot. They also demand more of your printer, your environment, and your workflow. This post is about what each of the main engineering filaments is actually good for, what your printer needs to run it, and the parts of the workflow that trip people up.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reading Print Failures: A Visual Diagnostic Guide for FDM</title>
      <link>/posts/reading-print-failures/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/reading-print-failures/</guid>
      <description>&lt;p&gt;A failed FDM print isn&amp;rsquo;t random. Every artifact — stringing, ringing, layer shifts, warping, elephant&amp;rsquo;s foot, zits, under-extrusion — has a physical cause, and in most cases the print itself tells you what went wrong. Experienced hobbyists can pick up a bad print, look at it for three seconds, and tell you the cause and the fix. That skill isn&amp;rsquo;t mystical. It&amp;rsquo;s pattern recognition.&lt;/p&gt;&#xA;&lt;p&gt;This post is the pattern reference. For each major failure mode, we&amp;rsquo;ll cover what it looks like, what&amp;rsquo;s physically happening, what the root causes are, and the fixes — ordered by likelihood, not by alphabet. The goal is that by the end you can look at a print and diagnose it instead of guessing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The 3D Printer Calibration Cookbook</title>
      <link>/posts/3d-printer-calibration-cookbook/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/3d-printer-calibration-cookbook/</guid>
      <description>&lt;p&gt;A factory-fresh printer is a printer that has never been calibrated. Out of the box, every machine — even a $1,500 CoreXY — ships with profiles that are intentionally conservative. They work, but they leave significant print quality and speed on the table, and they assume a filament the manufacturer picked, not the roll you actually bought.&lt;/p&gt;&#xA;&lt;p&gt;This cookbook walks the full calibration workflow in the order you should actually run it. Skip steps and you end up tuning against a moving target; do them in sequence and each test isolates one variable while the others stay fixed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Your First Layer, Every Time: The One Print Setting That Decides Everything</title>
      <link>/posts/your-first-layer-every-time/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/your-first-layer-every-time/</guid>
      <description>&lt;p&gt;Ask any experienced 3D printing hobbyist what separates reliable printing from frustrating printing, and the answer is always the same: &lt;strong&gt;the first layer&lt;/strong&gt;. Get it right, and the print almost prints itself. Get it wrong, and the rest of the print is an expensive, hours-long failure waiting to happen.&lt;/p&gt;&#xA;&lt;p&gt;First-layer failures are the number-one reason beginners quit the hobby. They&amp;rsquo;re also, by a wide margin, the easiest class of problem to solve once you understand what&amp;rsquo;s actually happening. This post covers the physics of first-layer adhesion, the tools that make it work (build surfaces, leveling, Z-offset), and the diagnostic skills to fix a bad first layer in 30 seconds instead of 30 minutes of reprints.&lt;/p&gt;</description>
    </item>
    <item>
      <title>3D Printing: A Getting Started Guide That Actually Sets Expectations</title>
      <link>/posts/3d-printing-getting-started/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/3d-printing-getting-started/</guid>
      <description>&lt;p&gt;Every beginner guide to 3D printing is written by someone who already owns a 3D printer, and it shows. The genre is full of cheerful &amp;ldquo;you&amp;rsquo;ll love it!&amp;rdquo; framing followed by a bill of materials and a parts diagram. That&amp;rsquo;s not the guide I want for someone who&amp;rsquo;s never printed before. I want a guide that answers, honestly: what is this hobby actually like on day 3, day 30, and day 300 — and is it the right hobby for you?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bambu Lab Lineup Compared: A1, P1S, X1C, H2D, and the X2D</title>
      <link>/posts/bambu-lab-lineup-compared/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bambu-lab-lineup-compared/</guid>
      <description>&lt;p&gt;Bambu Lab didn&amp;rsquo;t invent the consumer 3D printer, but it did reset expectations for what &amp;ldquo;out of the box&amp;rdquo; means in the category. Before the X1 Carbon landed in 2022, &amp;ldquo;consumer 3D printer&amp;rdquo; meant an Ender 3 you&amp;rsquo;d spend a weekend leveling, a Prusa i3 MK3 you&amp;rsquo;d build from a kit, or a Creality K1 you&amp;rsquo;d watch fail a first layer four times before something worked. After the X1C, &amp;ldquo;consumer 3D printer&amp;rdquo; meant unbox, click one button, and watch a benchy print correctly in under twenty minutes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building Modern Toolchains on Enterprise Linux: Python, Compilers, and Utilities on SLES 15 and Friends</title>
      <link>/posts/building-modern-toolchains-on-enterprise-linux/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/building-modern-toolchains-on-enterprise-linux/</guid>
      <description>&lt;p&gt;Enterprise Linux distributions are designed to be boring. SLES 15, RHEL 8/9, Ubuntu LTS — they ship a stable set of libraries, patch CVEs for a decade, and resist change. That&amp;rsquo;s exactly what a finance or EDA or HPC org wants running under its workloads. It is also, for engineers, a constant source of pain. The default Python is 3.6. &lt;code&gt;git&lt;/code&gt; is three versions behind. &lt;code&gt;cmake&lt;/code&gt; can&amp;rsquo;t build half the projects on GitHub. The users want &lt;code&gt;fd&lt;/code&gt;, &lt;code&gt;rg&lt;/code&gt;, &lt;code&gt;bat&lt;/code&gt;, &lt;code&gt;uv&lt;/code&gt;, &lt;code&gt;fzf&lt;/code&gt;, and a Python 3.13 with pandas 2.x. Your job is to give them that without breaking the OS underneath them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ghostty Terminal: Mitchell Hashimoto&#39;s GPU-Accelerated Terminal</title>
      <link>/posts/ghostty-terminal/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ghostty-terminal/</guid>
      <description>&lt;p&gt;Terminal emulators have had a strange recent renaissance. For twenty years the choices on a developer&amp;rsquo;s laptop were basically &amp;ldquo;the one that ships with your OS&amp;rdquo; or &amp;ldquo;iTerm2 on macOS&amp;rdquo; — and that was fine. Then Alacritty showed up in 2017 saying terminals could be GPU-accelerated and fast. Then Kitty added images and graphics protocols. Then WezTerm added a scripting language and cross-platform polish. And in late 2024 &lt;strong&gt;Ghostty&lt;/strong&gt; shipped its public release — a new terminal from Mitchell Hashimoto (HashiCorp founder, author of Vagrant and several other tools) that takes a careful, opinionated swing at what a modern terminal should be.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Helix Editor: Modal Editing Without Vim&#39;s Legacy</title>
      <link>/posts/helix-editor/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/helix-editor/</guid>
      <description>&lt;p&gt;Vim has run the modal-editor world since 1991. Neovim made it modern. Between them, they own the terminal-editor mindshare — and both carry thirty years of compatibility baggage. Ex-mode. The distinction between Normal, Insert, and Replace. Plugins installed via Git URLs and Vim Script. Config files that only Vim people can read. A learning curve that&amp;rsquo;s famously a cliff. It works, and millions of people love it, but the design was locked in before anyone had heard of an LSP.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Repurposing Old Phones and Mini PCs: Giving Retired Hardware a Second Act</title>
      <link>/posts/repurposing-old-phones-and-mini-pcs/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/repurposing-old-phones-and-mini-pcs/</guid>
      <description>&lt;p&gt;Every household has a drawer of abandoned hardware. The iPhone 8 that was retired because the battery couldn&amp;rsquo;t hold a charge through a morning. The Galaxy S9 replaced when the screen cracked a third time. A Dell OptiPlex 3050 that left the office during a refresh. A first-gen Intel NUC with a failing fan. These devices have eight-core ARM CPUs and 4-6GB of RAM, or dual-core x86 chips with 8GB and an SSD. They idle at 2-10W. They are, pound for pound, some of the most capable low-power computers in your house — and they&amp;rsquo;re doing nothing, or worse, they&amp;rsquo;re on their way to a landfill.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running a Homelab on a Power Budget</title>
      <link>/posts/homelab-on-a-power-budget/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/homelab-on-a-power-budget/</guid>
      <description>&lt;p&gt;The first electric bill after standing up a proper homelab is a humbling document. A used Dell R720 humming away in a closet, a 24-drive NAS, a desktop repurposed as a Plex box, a mini PC for Home Assistant, a 24-port PoE switch — innocent individually, catastrophic in aggregate. At 350W continuous draw, 24/7, that&amp;rsquo;s roughly 3,000 kWh per year. At typical 2026 residential rates in the US ($0.18/kWh) that&amp;rsquo;s $540; in Germany ($0.40/kWh) it&amp;rsquo;s $1,200. More than most cloud VPS bills. And that&amp;rsquo;s before summer AC struggles to pull the extra heat.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tiling Window Managers in 2026: Hyprland, Aerospace, and the End of the Linux Ghetto</title>
      <link>/posts/tiling-window-managers-2026/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tiling-window-managers-2026/</guid>
      <description>&lt;p&gt;For twenty years, tiling window managers were a Linux curiosity — the thing your coworker with the ThinkPad and the dotfiles repo used. i3 and awesome and xmonad were serious tools, but they lived in a world of keyboard-driven workflows, config files in exotic languages, and friends who said &amp;ldquo;just try it&amp;rdquo; with an evangelist&amp;rsquo;s smile while you nodded politely.&lt;/p&gt;&#xA;&lt;p&gt;That world has changed. In 2026, tiling WMs are no longer niche. &lt;strong&gt;Hyprland&lt;/strong&gt; on Linux has pulled the tiling aesthetic into the Wayland era with animations and eye candy that compete with macOS for visual polish. &lt;strong&gt;Aerospace&lt;/strong&gt; has brought i3-style tiling to macOS in a way that actually works with System Integrity Protection. Windows has tiling through FancyZones and PowerToys. There&amp;rsquo;s a tiling future in every major OS, and it no longer requires giving up your OS&amp;rsquo;s native look and feel.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zellij vs tmux: The Modern Terminal Multiplexer</title>
      <link>/posts/zellij-vs-tmux/</link>
      <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zellij-vs-tmux/</guid>
      <description>&lt;p&gt;tmux has been the default terminal multiplexer for a decade and a half. It is battle-tested, universal, and unavoidable on any serious Linux box. It is also, depending on how much honesty you want, charmingly crusty or actively user-hostile: a config language derived from set commands, modal prefix keys that conflict with every shortcut in every editor, and a plugin ecosystem glued together by &lt;code&gt;git clone&lt;/code&gt; into &lt;code&gt;~/.tmux/plugins&lt;/code&gt;. It works, but the UX has not aged gracefully.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ADRs in Practice: Architecture Decision Records That Teams Actually Read</title>
      <link>/posts/adrs-in-practice/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/adrs-in-practice/</guid>
      <description>&lt;p&gt;Every engineering team has the same conversation at least once a year. &amp;ldquo;Why are we using Postgres and not MongoDB?&amp;rdquo; &amp;ldquo;Who decided we&amp;rsquo;d build our own auth?&amp;rdquo; &amp;ldquo;Didn&amp;rsquo;t we agree on gRPC two years ago?&amp;rdquo; Someone goes to Confluence, finds three partially-conflicting documents and a deprecated Slack thread, and the team rediscovers the context the hard way — usually after reversing a decision that was actually fine.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Architecture Decision Records&lt;/strong&gt; (ADRs) are the antidote. A short, structured document for every significant decision: what we decided, why, what we considered, what the tradeoffs are. Committed to the repo alongside the code the decision affects. Immutable once accepted (new decisions supersede rather than edit). Read during onboarding. Referenced in code reviews.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BPF Performance Tools Tour: bcc, bpftrace, and libbpf</title>
      <link>/posts/bpf-performance-tools-tour/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bpf-performance-tools-tour/</guid>
      <description>&lt;p&gt;There&amp;rsquo;s a decent chance that the next time you diagnose a nasty Linux performance problem, the tool that actually cracks it will be built on eBPF. The ability to attach safe, JIT-compiled programs to kernel tracepoints, kprobes, uprobes, and scheduling events — and collect per-event data without noticeably perturbing the system — has reshaped Linux observability over the last decade. &lt;code&gt;strace&lt;/code&gt; was the old &amp;ldquo;attach to a running process and see what&amp;rsquo;s happening&amp;rdquo;; eBPF is the modern equivalent that works at production scale.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Delta Lake vs Iceberg vs Hudi: The Table Format Shootout</title>
      <link>/posts/delta-lake-vs-iceberg-vs-hudi/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/delta-lake-vs-iceberg-vs-hudi/</guid>
      <description>&lt;p&gt;Somewhere around 2017, people realized that putting Parquet files in an S3 bucket and calling it a &amp;ldquo;data lake&amp;rdquo; produced a technology that was cheap and scalable and fundamentally broken. You could not do atomic updates. You could not reliably append without corrupting concurrent readers. You could not evolve a schema without rewriting everything. You could not know what a query would return if someone was writing at the same time. Lakes were blobs. Warehouses had been solving these problems for forty years and lakes, for all their storage economics, were a regression.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Diátaxis for Technical Writing: The Framework Behind Great Docs</title>
      <link>/posts/diataxis-for-technical-writing/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/diataxis-for-technical-writing/</guid>
      <description>&lt;p&gt;You can tell the moment a documentation site was designed by committee. There&amp;rsquo;s a &amp;ldquo;Getting Started&amp;rdquo; page that assumes you already understand the system. There&amp;rsquo;s a reference that reads like a tutorial halfway through. There&amp;rsquo;s a &amp;ldquo;Guide&amp;rdquo; page that mixes conceptual background, step-by-step instructions, and a list of every option the function accepts. Users land on it, skim for thirty seconds, give up, and open an issue asking a question the docs theoretically answer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Event Sourcing and CQRS in Production</title>
      <link>/posts/event-sourcing-and-cqrs/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/event-sourcing-and-cqrs/</guid>
      <description>&lt;p&gt;Event sourcing is one of those architectures that sounds inevitable until you run it for a year. The pitch is seductive: store &lt;em&gt;what happened&lt;/em&gt;, not &lt;em&gt;what is&lt;/em&gt;. Replay the events to reconstruct any view. Have complete history by default. Audit is free. Time travel is free. New read models are cheap because you can project the event log into whatever shape you want.&lt;/p&gt;&#xA;&lt;p&gt;Then you ship, and reality arrives. Projections fall behind. Schema changes require careful migrations. The event log is the source of truth, so bugs in events are bugs in history. Developers unfamiliar with the pattern write commands that bypass the event stream. The log grows forever. You need to rebuild a projection and realize it&amp;rsquo;ll take 14 hours.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Flamegraphs: Reading and Generating</title>
      <link>/posts/flamegraphs-reading-and-generating/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/flamegraphs-reading-and-generating/</guid>
      <description>&lt;p&gt;Reading a stack profile as text is like reading a waterfall diagram one line at a time. You can do it, but the shape of the problem — which paths dominate, which call stacks are identical, where the CPU is really spending time — doesn&amp;rsquo;t pop until you see it rendered.&lt;/p&gt;&#xA;&lt;p&gt;Brendan Gregg&amp;rsquo;s flamegraph visualization was the breakthrough that turned profiling from a specialist activity into something engineers actually enjoy. The trick is deceptively simple: take every stack trace from your profile, stack them up vertically, merge identical prefixes, and color them. The wide boxes at the top are where time is being spent. Anyone on your team can point at a 40% wide yellow bar and say &amp;ldquo;that&amp;rsquo;s the hot path.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>FSDP and DDP: Distributed Training Patterns That Actually Scale</title>
      <link>/posts/fsdp-and-ddp-distributed-training/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fsdp-and-ddp-distributed-training/</guid>
      <description>&lt;p&gt;Training a model on one GPU is a notebook exercise. Training the same model on eight GPUs — let alone sixty-four across eight nodes — requires picking a parallelism strategy, configuring a collective communication library, pinning threads, choosing a precision scheme, and paying attention to roughly forty knobs nobody warned you about. The first time a distributed training job hangs silently while every GPU sits at 100% utilization, you start to appreciate that &amp;ldquo;just add more GPUs&amp;rdquo; is not, in fact, a strategy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>perf: Linux&#39;s Best Profiler</title>
      <link>/posts/perf-linux-profiler/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/perf-linux-profiler/</guid>
      <description>&lt;p&gt;Every serious Linux performance investigation eventually ends at &lt;code&gt;perf&lt;/code&gt;. Not because it&amp;rsquo;s pretty — the man page is vast, the UI is terse, and the output takes real study to read — but because &lt;code&gt;perf&lt;/code&gt; is the tool that actually shows you what the CPU is doing. Flamegraphs, eBPF tools, Java agents, Python profilers: many of them either wrap &lt;code&gt;perf&lt;/code&gt; directly or exist to expose data that &lt;code&gt;perf&lt;/code&gt; collects.&lt;/p&gt;&#xA;&lt;p&gt;This post is the practical guide I wish I had when I first started profiling Linux systems seriously. It covers the subcommands you&amp;rsquo;ll actually use (&lt;code&gt;stat&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;record&lt;/code&gt;/&lt;code&gt;report&lt;/code&gt;, &lt;code&gt;script&lt;/code&gt;), what performance counters mean and how to read them, the knobs that catch everyone (frame pointers, kernel permissions, symbol resolution), and enough of the CPU microarchitecture vocabulary to make sense of what perf tells you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Strangler Fig for Legacy Migrations: Replacing Systems Without the Big Rewrite</title>
      <link>/posts/strangler-fig-legacy-migrations/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/strangler-fig-legacy-migrations/</guid>
      <description>&lt;p&gt;Every software engineer eventually faces a legacy system that needs to be replaced. The reasoning is always roughly the same: the code is twelve years old, written in a language three of the original authors don&amp;rsquo;t use anymore, running on an OS version security told us about last year, hosting critical business logic in stored procedures nobody dares edit. Everyone agrees it should be replaced. Everyone is scared to propose the project, because everyone has seen — or been part of — a multi-year rewrite that ended in a bonfire of regret.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Outbox Pattern: Reliable Messaging Without Distributed Transactions</title>
      <link>/posts/outbox-pattern/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/outbox-pattern/</guid>
      <description>&lt;p&gt;Every distributed system eventually runs into the same problem: a service updates its database &lt;em&gt;and&lt;/em&gt; needs to publish a message to the outside world. A user signs up — the &lt;code&gt;users&lt;/code&gt; row is written and an email-welcome event should be published. An order is placed — the &lt;code&gt;orders&lt;/code&gt; row is written and a &amp;ldquo;send this to fulfillment&amp;rdquo; event should flow. Two writes, to two systems, ideally both happening or neither. If one succeeds and the other fails, you&amp;rsquo;ve created an invisible bug.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The USE and RED Methods: Systematic Performance Investigation</title>
      <link>/posts/use-and-red-methods/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/use-and-red-methods/</guid>
      <description>&lt;p&gt;The worst kind of performance investigation is one where you&amp;rsquo;re looking at a Grafana dashboard full of graphs and you don&amp;rsquo;t know which one to read first. You click around for a while, pull some metrics, notice something that looks suspicious, follow the thread, hit a dead end, start again. Forty minutes later, your understanding of the system is slightly richer and the user is still waiting.&lt;/p&gt;&#xA;&lt;p&gt;The USE and RED methods are antidotes. They are checklists — methodologies, if you want the fancier word — that tell you exactly what to look at first, in what order, for any performance investigation. Neither is complicated. Both are under-adopted. Together they cover the two most important questions: &amp;ldquo;is my &lt;em&gt;resource&lt;/em&gt; healthy?&amp;rdquo; (USE, from Brendan Gregg) and &amp;ldquo;is my &lt;em&gt;service&lt;/em&gt; healthy?&amp;rdquo; (RED, from Tom Wilkie). Applied consistently, they turn a large fraction of performance investigations from improvisation into routine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Triton Inference Server: Production ML Serving That Actually Scales</title>
      <link>/posts/triton-inference-server/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/triton-inference-server/</guid>
      <description>&lt;p&gt;Somewhere between &amp;ldquo;we trained a model&amp;rdquo; and &amp;ldquo;we serve a hundred thousand requests per second&amp;rdquo; there is a gulf that swallows weekends. Serving inference at scale is not a solved problem you inherit from a tutorial. You will hit batching strategy, memory fragmentation, GPU utilization, model format conversions, dynamic shapes, request concurrency, and half a dozen other things the notebook never warned you about.&lt;/p&gt;&#xA;&lt;p&gt;NVIDIA Triton Inference Server is the most complete open-source answer to that problem. It is the workhorse behind a huge fraction of production ML serving at major AI companies and cloud providers. It runs inside SageMaker endpoints, Vertex AI, Azure ML, and countless on-prem deployments. If you serve ML models to real users, there is a good chance you will meet Triton eventually.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apache Airflow Deep Dive: DAGs, Executors, and Production Realities</title>
      <link>/posts/apache-airflow-deep-dive/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apache-airflow-deep-dive/</guid>
      <description>&lt;p&gt;Apache Airflow is the default answer to &amp;ldquo;what should I use to orchestrate my data pipelines?&amp;rdquo; despite a loud chorus of newer tools (Dagster, Prefect, Temporal, Argo Workflows) trying to take its throne. It has won that position through sheer ubiquity — if you work in data, there is a non-trivial chance you have inherited an Airflow deployment at some point, whether you wanted to or not.&lt;/p&gt;&#xA;&lt;p&gt;This post is the guide I wish existed when I first had to run Airflow in production. It covers what makes Airflow what it is, where its abstractions leak, how to write DAGs that stay maintainable past the first six months, which executor to pick, and how it compares to modern alternatives. I will assume Airflow 2.x with some references to 3.0 changes where they matter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apache Spark Fundamentals: RDDs, DataFrames, Catalyst, and When Spark Still Wins</title>
      <link>/posts/apache-spark-fundamentals/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apache-spark-fundamentals/</guid>
      <description>&lt;p&gt;Apache Spark has spent more than a decade as the default choice for large-scale data processing. In that time the ecosystem has changed dramatically — DuckDB runs real analytical workloads on a laptop, Trino and Presto dominate ad-hoc querying, Flink owns streaming for many teams, and Polars has eaten a chunk of the single-node work Spark used to do. Yet Spark keeps growing. It is the compute engine under Databricks, AWS EMR, Google Dataproc, Azure Synapse, Snowflake&amp;rsquo;s Snowpark, and most on-prem lakehouse deployments. Knowing Spark well is still one of the highest-leverage skills a data engineer can have.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ArgoCD ApplicationSets Patterns</title>
      <link>/posts/argocd-applicationsets-patterns/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/argocd-applicationsets-patterns/</guid>
      <description>&lt;p&gt;When you first adopt ArgoCD, you write Application manifests by hand. One YAML file per (app, cluster) pair, maybe a bit of Kustomize or Helm to vary the values, but each Application is a deliberate, named object. This works beautifully until you look up and realize you have 40 services × 4 environments × 3 clusters = 480 Application manifests, all nearly identical, all drifting out of sync because nobody remembered to copy the change into dev-staging-use1 when they did it for prod-eu2.&lt;/p&gt;</description>
    </item>
    <item>
      <title>auditd: Linux&#39;s Syscall Logger</title>
      <link>/posts/auditd-linux-syscall-logger/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/auditd-linux-syscall-logger/</guid>
      <description>&lt;p&gt;&lt;code&gt;auditd&lt;/code&gt; is the Linux audit daemon — the part of the kernel and userspace that logs security-relevant events at the syscall level. File access, privilege escalation, network changes, authentication events, module loading, all with process ancestry and user identity attached. It&amp;rsquo;s a mandatory tool for PCI DSS, HIPAA, FedRAMP, CMMC, and most other compliance frameworks, and a genuinely useful security tool even outside compliance contexts.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s also confusing, verbose, and the default config ships empty. Nothing gets logged until you write rules, and once you do, you can easily generate gigabytes of noise that buries the signal you actually wanted. This post covers auditd as an operational tool: the kernel-userspace split, writing rules that produce useful logs, searching with &lt;code&gt;ausearch&lt;/code&gt;/&lt;code&gt;aureport&lt;/code&gt;, shipping to a SIEM, and the compliance-recipe templates for common regulatory requirements.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BIOS/UEFI Deep Dive: Boot Phases, Secure Boot, Measured Boot, and TPM</title>
      <link>/posts/bios-uefi-deep-dive/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bios-uefi-deep-dive/</guid>
      <description>&lt;p&gt;Most of us meet UEFI only when something has gone wrong. The machine won&amp;rsquo;t boot a new disk, Secure Boot is rejecting a freshly-compiled kernel module, or a Windows update has overwritten the EFI entries and Linux is invisible. You spelunk into the BIOS setup screen, poke around, fix the symptom, and close the book. UEFI is a 2000-page specification, a small operating system running before your operating system, and an open attack surface that modern defenders care about a great deal. Understanding it pays back whenever firmware is involved — bootloaders, hardware provisioning, measured boot, remote attestation, full-disk encryption that unlocks automatically, Secure Boot custom key enrollment, or merely debugging why grub stopped working.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cilium as a Full CNI: Beyond Observability</title>
      <link>/posts/cilium-as-a-full-cni/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cilium-as-a-full-cni/</guid>
      <description>&lt;p&gt;Cilium started life as &amp;ldquo;eBPF-based observability for Kubernetes&amp;rdquo;. That framing sold it short. In 2026 Cilium is a full CNI that replaces kube-proxy, implements identity-based network policy, does BGP peering, operates as a service mesh, extends across clusters, handles egress gateway functionality, and terminates load balancing in hardware via XDP. It&amp;rsquo;s become the default networking layer in Google&amp;rsquo;s GKE Dataplane V2, Amazon&amp;rsquo;s EKS distro, and most on-prem Kubernetes distributions that care about performance.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Consul Service Discovery and Service Mesh</title>
      <link>/posts/consul-service-discovery-and-mesh/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/consul-service-discovery-and-mesh/</guid>
      <description>&lt;p&gt;Before Consul, &amp;ldquo;service discovery&amp;rdquo; on most networks meant hardcoding IP addresses, putting hostnames in a config file, or running a round-robin DNS entry that took 30 seconds to propagate and didn&amp;rsquo;t understand &amp;ldquo;this instance is unhealthy.&amp;rdquo; After Consul, service discovery means &lt;code&gt;postgres.service.consul&lt;/code&gt; resolves to a currently-healthy postgres instance in a few milliseconds and stops doing so the moment the instance fails a health check. That shift — from static to dynamic, from &amp;ldquo;config file&amp;rdquo; to &amp;ldquo;runtime query&amp;rdquo; — is the payoff of every service discovery tool, and Consul is one of the oldest and most mature implementations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DNSSEC Setup and Operation: KSK/ZSK Rotation, DS Publication, and Validation Debugging</title>
      <link>/posts/dnssec-setup-and-operation/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dnssec-setup-and-operation/</guid>
      <description>&lt;p&gt;DNSSEC (Domain Name System Security Extensions) is the set of protocol extensions that cryptographically sign DNS records, preventing spoofing, cache poisoning, and bogus responses from MITM attackers between your resolver and the authoritative name servers. It&amp;rsquo;s been around since 1997 (original RFCs), widely deployed in TLDs since the root zone signing in 2010, and still the subject of operational confusion every time someone tries to deploy it. This post is the DNSSEC explanation that walks you from &amp;ldquo;why&amp;rdquo; to &amp;ldquo;how&amp;rdquo; without losing you at DNSKEY syntax on page three.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FRRouting in Production: The Linux Router That Replaces Cisco for Many Use Cases</title>
      <link>/posts/frrouting-in-production/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/frrouting-in-production/</guid>
      <description>&lt;p&gt;FRRouting — FRR for short — is the routing stack that quietly runs under some of the most demanding modern network deployments: Cumulus Linux (now NVIDIA), SONiC, Cilium&amp;rsquo;s BGP mode, MetalLB, Vyatta/VyOS forks, Calico&amp;rsquo;s route reflector, and the Linux routers inside countless small ISPs and enterprises. If you&amp;rsquo;ve used any of those, you&amp;rsquo;ve used FRR. And if you&amp;rsquo;ve ever looked at Cisco or Juniper pricing for a medium-sized branch router and winced, FRR on commodity hardware is often a serious alternative.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GPU Passthrough End-to-End</title>
      <link>/posts/gpu-passthrough-end-to-end/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gpu-passthrough-end-to-end/</guid>
      <description>&lt;p&gt;GPU passthrough is one of those features that, on paper, is simple: take a PCIe device, hand it exclusively to a VM, let the VM&amp;rsquo;s driver talk to it as if it owned the hardware. In practice, it&amp;rsquo;s a maze of kernel modules, firmware quirks, vendor-specific countermeasures, and Windows error codes that seem designed to make you give up. The good news is that once you understand the four or five layers that have to line up, you can troubleshoot anything from &amp;ldquo;the host crashes when the VM starts&amp;rdquo; to the infamous NVIDIA Error 43.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HashiCorp Nomad: A Simpler Kubernetes Alternative</title>
      <link>/posts/hashicorp-nomad/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hashicorp-nomad/</guid>
      <description>&lt;p&gt;Kubernetes is the default answer to &amp;ldquo;how do I run containers at scale,&amp;rdquo; and most of the time it&amp;rsquo;s a fine one. But &amp;ldquo;most of the time&amp;rdquo; hides a real distribution of teams who either don&amp;rsquo;t need the complexity, don&amp;rsquo;t need just-containers, or are burning a disproportionate fraction of their engineering effort on the platform itself rather than what it runs. HashiCorp Nomad is the answer when you want most of what Kubernetes gives you without most of what Kubernetes asks from you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IPMI and Redfish: Out-of-Band Management for Humans</title>
      <link>/posts/ipmi-and-redfish/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ipmi-and-redfish/</guid>
      <description>&lt;p&gt;Every server you own has a second computer inside it that you rarely think about. It&amp;rsquo;s on the same chassis, it draws a few watts whether the main CPU is running or not, and it has its own Ethernet port, its own web UI, its own CPU, and its own operating system. It&amp;rsquo;s called the BMC — Baseboard Management Controller — and it&amp;rsquo;s the reason you can reboot a wedged server at 3 a.m. from your couch instead of driving to the datacenter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kea DHCP: The Successor to ISC DHCP</title>
      <link>/posts/kea-dhcp/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kea-dhcp/</guid>
      <description>&lt;p&gt;ISC DHCP (&lt;code&gt;dhcpd&lt;/code&gt;) served the internet for 25+ years. It shipped on every mainstream Linux distro, ran in front of almost every corporate LAN, and was the definitive reference implementation of DHCP. On October 5, 2022, ISC officially ended support. The successor — from the same organization — is &lt;strong&gt;Kea&lt;/strong&gt;, a ground-up rewrite with a JSON configuration model, hooks for dynamic behavior, a REST API, and HA baked in.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re still running &lt;code&gt;dhcpd.conf&lt;/code&gt;, this post is your migration guide. If you&amp;rsquo;re starting fresh, it&amp;rsquo;s your explanation of why Kea is the current answer. Kea isn&amp;rsquo;t a drop-in replacement — the config syntax is completely different — but the conceptual model is similar, and the features are an upgrade on every dimension.&lt;/p&gt;</description>
    </item>
    <item>
      <title>KVM/libvirt Without Proxmox</title>
      <link>/posts/kvm-libvirt-without-proxmox/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kvm-libvirt-without-proxmox/</guid>
      <description>&lt;p&gt;Proxmox is a fine piece of software. It takes a heap of excellent Linux virtualization primitives — KVM, QEMU, libvirt, LXC, Corosync, ZFS — and wraps them in a web UI that hides most of the complexity. That&amp;rsquo;s great when you&amp;rsquo;re spinning up a lab quickly and terrible when something breaks at 2 a.m. and you&amp;rsquo;ve never looked at the layers underneath. The web UI turns into a black box, and the first time you need to understand why your VM won&amp;rsquo;t boot or why &lt;code&gt;virsh&lt;/code&gt; shows a state the UI disagrees with, you&amp;rsquo;re reverse-engineering the abstraction instead of operating the system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenTofu vs Terraform: The Fork One Year In</title>
      <link>/posts/opentofu-vs-terraform/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opentofu-vs-terraform/</guid>
      <description>&lt;p&gt;In August 2023, HashiCorp changed Terraform&amp;rsquo;s license from MPL 2.0 to BSL 1.1 (Business Source License). By January 2024, the Linux Foundation had adopted a fork called OpenTofu. Eighteen months later we are living with the consequences: two tools that share a heritage and most of their DNA, diverging slowly, with a community of users trying to decide which one they actually want to be on for the next decade. This post is the view from where we are now — what the licensing change meant, what actually differs between the tools, where they have diverged technically, what the migration path looks like, and how the decision plays out for teams of different sizes and postures.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OSPF for DevOps Engineers: Link-State Routing Without the CCNA</title>
      <link>/posts/ospf-for-devops-engineers/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ospf-for-devops-engineers/</guid>
      <description>&lt;p&gt;OSPF (Open Shortest Path First) is the most widely-deployed interior routing protocol in existence. It runs inside datacenters, campuses, ISPs, and — increasingly — Linux-based homelab routers using FRRouting (FRR). If you&amp;rsquo;ve ever wanted to run multiple routers in your lab and have them figure out routes automatically, or needed to understand what a network engineer is talking about when they mention &amp;ldquo;Area 0&amp;rdquo; and &amp;ldquo;Type 5 LSAs&amp;rdquo;, this post is for you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PAM Configuration Deep Dive</title>
      <link>/posts/pam-configuration-deep-dive/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pam-configuration-deep-dive/</guid>
      <description>&lt;p&gt;PAM — the Pluggable Authentication Modules framework — is the layer that decides whether you get a shell, whether &lt;code&gt;sudo&lt;/code&gt; trusts you, whether &lt;code&gt;sshd&lt;/code&gt; lets you past the password prompt, and whether your screen locker believes you are really you. It has been sitting under your login prompt since 1995, and most engineers know enough PAM to be dangerous: they can copy a stanza from a blog post into &lt;code&gt;/etc/pam.d/sshd&lt;/code&gt;, but when a failed login produces a silent rejection at 2 a.m., they cannot read the config they are looking at.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PCIe for Systems Engineers</title>
      <link>/posts/pcie-for-systems-engineers/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pcie-for-systems-engineers/</guid>
      <description>&lt;p&gt;PCIe is the bus. Every NVMe drive, every GPU, every NIC faster than gigabit, every serious accelerator, and every modern chipset talks to the CPU through it. Most sysadmins have a working relationship with PCIe that starts and ends at &lt;code&gt;lspci&lt;/code&gt;. That&amp;rsquo;s fine for a while. The day your GPU trains at half speed, your NVMe drive benchmarks at a third of its rated IOPS, or your bifurcation card doesn&amp;rsquo;t split the slot the way you expected, you find yourself looking at &lt;code&gt;lspci -vvv&lt;/code&gt; output and realizing the letters and numbers you&amp;rsquo;ve been scrolling past for years actually mean things.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SELinux in Practice (Not &#39;Disable It&#39;)</title>
      <link>/posts/selinux-in-practice/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/selinux-in-practice/</guid>
      <description>&lt;p&gt;Every sysadmin has been there. A service won&amp;rsquo;t start. Logs are cryptic. Someone googles the problem and the top answer says &amp;ldquo;set SELinux to permissive and try again&amp;rdquo;. It works. The problem is forgotten. SELinux stays permissive forever, the one security feature RHEL shipped specifically to prevent this class of escalation is now neutered, and a year later when the service is compromised by a directory traversal bug, the attacker gets the keys to everything.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Standalone Ceph Without Proxmox: cephadm, Pool Design, and Day-2 Operations</title>
      <link>/posts/standalone-ceph-without-proxmox/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/standalone-ceph-without-proxmox/</guid>
      <description>&lt;p&gt;Ceph is the distributed storage system that quietly runs under most large-scale open source storage stacks — OpenStack clouds, CERN&amp;rsquo;s physics workloads, DigitalOcean&amp;rsquo;s Spaces, Bloomberg&amp;rsquo;s internal platforms. It&amp;rsquo;s also the storage layer most homelab users first encounter through Proxmox, which hides almost all of Ceph&amp;rsquo;s complexity behind a web UI.&lt;/p&gt;&#xA;&lt;p&gt;This post is about what happens when you want Ceph &lt;em&gt;without&lt;/em&gt; Proxmox: running it on plain Linux with &lt;code&gt;cephadm&lt;/code&gt;, designing pools and CRUSH rules for your hardware, exposing RBD/RGW/CephFS, and operating it day 2. Ceph is not a casual install — you will spend a weekend learning it even in the simplest setup — but once it&amp;rsquo;s running, it&amp;rsquo;s one of the most flexible storage systems available.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vault Beyond Secrets: PKI, SSH CA, and Dynamic DB Credentials</title>
      <link>/posts/vault-beyond-secrets/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vault-beyond-secrets/</guid>
      <description>&lt;p&gt;Most people who use Vault use it as a key-value store with authentication. A Python app reads &lt;code&gt;secret/data/app/config&lt;/code&gt;, gets back a JSON blob, parses out a DB password, and connects. That&amp;rsquo;s fine, and that&amp;rsquo;s what most documentation and tutorials focus on. But Vault&amp;rsquo;s KV secrets engine is the least interesting thing about it. The stuff that separates Vault from, say, writing secrets to S3 with KMS encryption and calling it a day, is the &lt;strong&gt;dynamic&lt;/strong&gt; secrets engines — the ones that &lt;em&gt;generate&lt;/em&gt; credentials on demand rather than &lt;em&gt;store&lt;/em&gt; them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wazuh HIDS: Self-Hosted Alternative to CrowdStrike and Falcon</title>
      <link>/posts/wazuh-hids/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wazuh-hids/</guid>
      <description>&lt;p&gt;If you have ever priced out a commercial EDR for a fleet of a few hundred Linux boxes, you know the quiet drawer where budget proposals go to die. CrowdStrike Falcon, SentinelOne, and Microsoft Defender for Endpoint all produce genuinely good telemetry, but the per-endpoint pricing does not scale graciously for academic clusters, research labs, or mid-sized companies with a heavy infrastructure footprint. At some point you find yourself asking whether the open-source world has a serious answer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wireshark and tshark for Engineers: Capture Filters, Display Filters, and Scripting Batch Analysis</title>
      <link>/posts/wireshark-tshark-for-engineers/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wireshark-tshark-for-engineers/</guid>
      <description>&lt;p&gt;Wireshark is the packet analyzer that&amp;rsquo;s existed in one form or another since 1998 (when it was called Ethereal). It remains the tool you reach for when network behavior doesn&amp;rsquo;t match expectation: the one that tells you, at the wire level, what&amp;rsquo;s actually happening. Everyone has used it. Most people use 10% of its features. This post is about the rest — the parts that make the difference between &amp;ldquo;I took a packet capture and looked around&amp;rdquo; and &amp;ldquo;I diagnosed the problem in 30 seconds because I knew what to filter for&amp;rdquo;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>YubiKey for SSH, GPG, sudo, and FIDO2</title>
      <link>/posts/yubikey-ssh-gpg-sudo-fido2/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/yubikey-ssh-gpg-sudo-fido2/</guid>
      <description>&lt;p&gt;A YubiKey is a small USB device that can do more interesting work than the marketing copy suggests. Most people know it as &amp;ldquo;the thing you tap to log into Google.&amp;rdquo; A YubiKey 5 is actually four or five distinct security tokens in one piece of hardware: a FIDO2 authenticator, a PIV smart card, an OpenPGP smart card, an OATH (TOTP/HOTP) store, and a YubiOTP module. Each of those can be used independently, and a reasonably paranoid engineer can route &lt;strong&gt;every&lt;/strong&gt; authentication on their machine — SSH, GPG signing, sudo, browser logins, disk unlock — through the same hardware, with every private operation requiring a physical touch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Btrfs in Production: Snapshots, Send/Receive, Quotas, and the Pitfalls</title>
      <link>/posts/btrfs-in-production/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/btrfs-in-production/</guid>
      <description>&lt;p&gt;Btrfs has a strange reputation. It is the default root filesystem on openSUSE and Fedora Workstation. It powers Synology&amp;rsquo;s BTRFS volume type. It survives in Facebook&amp;rsquo;s fleet. And yet an entire generation of sysadmins still avoids it, remembers the RAID5/6 warnings from 2017, and tells you to use ZFS or XFS. The truth is more nuanced: Btrfs is excellent at some things, dangerous at others, and the dangerous parts have been clearly documented for years. This post walks through what it actually gets right — snapshots, send/receive, transparent compression, reflinks, subvolume-based layouts — and the pitfalls that earned it its reputation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Environment Modules with Lmod: How `module load` Actually Works</title>
      <link>/posts/environment-modules-with-lmod/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/environment-modules-with-lmod/</guid>
      <description>&lt;p&gt;Every HPC user has typed &lt;code&gt;module load gcc/13.2.0 openmpi/5.0.1&lt;/code&gt; and watched their compiler, MPI library, and a dozen environment variables magically rearrange themselves. It looks like black magic the first time. It is not. It is a reasonably thin Lua script manipulating shell environment variables — and once you understand the mechanism, you can build a software tree that serves hundreds of users with conflicting toolchain requirements and no filesystem collisions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>fio Benchmarking Cookbook: Stop Using dd, Start Measuring What Matters</title>
      <link>/posts/fio-benchmarking-cookbook/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fio-benchmarking-cookbook/</guid>
      <description>&lt;p&gt;&lt;code&gt;dd if=/dev/zero of=/tmp/test bs=1M count=1000&lt;/code&gt; tells you almost nothing useful about your storage. It measures sequential write throughput of zero-filled data to a single-threaded userspace buffered I/O path, on a filesystem that may have deduplicated or compressed it away entirely, in a cache-warm scenario that won&amp;rsquo;t represent any real workload. If this is how you&amp;rsquo;ve been benchmarking storage, this post is for you.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;fio&lt;/code&gt; — the Flexible I/O Tester by Jens Axboe (the Linux block layer maintainer and author of &lt;code&gt;io_uring&lt;/code&gt;) — is the tool that replaces &lt;code&gt;dd&lt;/code&gt;, &lt;code&gt;bonnie++&lt;/code&gt;, &lt;code&gt;iozone&lt;/code&gt;, and your homemade Bash scripts. It can simulate virtually any I/O pattern with precision: sequential or random, reads or writes or mixes, direct or buffered, synchronous or asynchronous, with any block size, queue depth, and concurrency. This post is a practical cookbook: the job files you actually need, how to read the output, and how to avoid benchmarking fiction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FlexLM and RLM License Server Internals: Debugging Denials, Borrowing, and Building License-Aware Schedulers</title>
      <link>/posts/flexlm-and-rlm-license-server-internals/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/flexlm-and-rlm-license-server-internals/</guid>
      <description>&lt;p&gt;Every serious EDA shop eventually hits the license server problem. You own N seats of a tool, you have 2N engineers, and somehow the answer to &amp;ldquo;can I run my simulation right now?&amp;rdquo; depends on a TCP service that was designed in the early 1990s, is configured through text files that look like Lisp forms stapled to Fortran, and returns errors that read like &amp;ldquo;&lt;code&gt;-97,121:2 &amp;quot;Can&#39;t connect to license server system.&amp;quot; System Error: 115&lt;/code&gt;&amp;rdquo; when things go wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LEF/DEF Formats Explained: The Physical Design Data Everyone Ships But Nobody Teaches</title>
      <link>/posts/lef-def-formats-explained/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/lef-def-formats-explained/</guid>
      <description>&lt;p&gt;If you have spent any time near an ASIC flow, you have seen LEF and DEF files. They are the ubiquitous physical-design file formats that describe standard cell libraries, technology rules, and the layout of a design at various stages of place-and-route. Every major EDA tool reads and writes them. Every PDK ships them. Most digital designers use them without ever reading the spec.&lt;/p&gt;&#xA;&lt;p&gt;The gap between &amp;ldquo;uses them&amp;rdquo; and &amp;ldquo;understands them&amp;rdquo; is large, and closing it changes how you read tool output, how you debug physical issues, and how you integrate open-source EDA tools (OpenROAD, KLayout, Magic) into a real flow. This post is a first-principles walkthrough of what LEF and DEF actually contain, what each major section is for, how the tools consume them, and the practical operations — merging, sanitizing, converting — that physical design engineers do with them every week.&lt;/p&gt;</description>
    </item>
    <item>
      <title>LUKS and Full-Disk Encryption: Root Partitions, TPM Unlock, and Key Management</title>
      <link>/posts/luks-full-disk-encryption/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/luks-full-disk-encryption/</guid>
      <description>&lt;p&gt;Linux Unified Key Setup (LUKS) is the standard full-disk encryption on Linux. It ships in every mainstream distro installer, backs the volume encryption for ext4/XFS/Btrfs on top of &lt;code&gt;dm-crypt&lt;/code&gt;, and quietly protects laptops, servers, and removable drives around the world. Like most things that ship by default, the installer gets you 80% of the way — the remaining 20% (key rotation, TPM-backed unlock, headers, keyslots, recovery plans) is where production use lives, and where most people run into trouble years later when a drive fails and they realize they never actually thought about recovery.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MinIO: Self-Hosted S3 — Deployment, Erasure Coding, and Performance Tuning</title>
      <link>/posts/minio-self-hosted-s3/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/minio-self-hosted-s3/</guid>
      <description>&lt;p&gt;MinIO is the S3-compatible object storage server most people reach for when they need &amp;ldquo;S3, but not AWS&amp;rdquo;. It&amp;rsquo;s a single Go binary that can run on a laptop, scale to multi-node clusters serving petabytes, and claims line-rate throughput on commodity hardware. It&amp;rsquo;s also the subject of occasional community friction around licensing and the recent removal of the web console from the community edition. This post focuses on what it is, how it works, and how to run it well — not the licensing drama.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MPI Programming Essentials: Collectives, Non-Blocking, and the Traps Nobody Warns You About</title>
      <link>/posts/mpi-programming-essentials/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mpi-programming-essentials/</guid>
      <description>&lt;p&gt;If you want to run a program across more than one machine in an HPC cluster, you are almost certainly going to write MPI. Three decades after its introduction, the Message Passing Interface is still the dominant model for distributed-memory parallelism — it runs every major weather model, every serious CFD code, every computational chemistry package, and the communication layer underneath most large-scale ML frameworks.&lt;/p&gt;&#xA;&lt;p&gt;MPI is not hard to learn. MPI is hard to learn &lt;em&gt;well&lt;/em&gt;. The API surface is enormous (600+ functions), the most common tutorials teach patterns that perform terribly at scale, and the error messages when you mess up are historically unhelpful. This post is the working-engineer companion: enough theory to understand what the runtime is doing, the ~20 functions you&amp;rsquo;ll actually use, and the failure modes nobody warns you about until you&amp;rsquo;ve spent a week debugging them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NCCL Deep Dive: Multi-GPU Collectives, Ring vs Tree, and Debugging Distributed Training</title>
      <link>/posts/nccl-deep-dive/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nccl-deep-dive/</guid>
      <description>&lt;p&gt;When a 70-billion-parameter model is training across 512 GPUs, the all-reduce that synchronizes gradients every step has to move tens of gigabytes of data between every pair of nodes, finish in tens of milliseconds, and not drop the bandwidth of the most expensive hardware in the datacenter. The library doing that work is almost always &lt;strong&gt;NCCL&lt;/strong&gt; — NVIDIA&amp;rsquo;s Collective Communication Library — and when it hangs or underperforms, training is down until you can figure out why.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenMP: Threading Without Pthreads (And Without the Nightmares)</title>
      <link>/posts/openmp-threading-without-pthreads/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/openmp-threading-without-pthreads/</guid>
      <description>&lt;p&gt;If you have ever written pthreads code — spinning up threads, juggling mutexes, reasoning about memory ordering, and forgetting to join one of them — you already know why OpenMP exists. For the large class of problems where you just want to parallelize a loop, fan out independent tasks, or offload a kernel to a GPU, OpenMP lets you do it with a pragma instead of a plumbing project.&lt;/p&gt;&#xA;&lt;p&gt;OpenMP is not magic. It is a layer of compiler-understood directives plus a small runtime that does the thread management you would have written yourself. The directives are declarative (&amp;ldquo;this loop is parallel, these variables are private&amp;rdquo;), which means the compiler and runtime can vary the implementation — number of threads, scheduling, placement — without you rewriting your code. That is exactly the trade you want for compute-heavy numeric code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Parallel Filesystems Compared: Lustre vs BeeGFS vs GPFS vs Weka</title>
      <link>/posts/parallel-filesystems-compared/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/parallel-filesystems-compared/</guid>
      <description>&lt;p&gt;There is a moment in the growth of any compute cluster when NFS stops working. You can feel it: the scheduler shows 500 jobs running, but they are all waiting on I/O; your file server is at 100% CPU; the &lt;code&gt;ls&lt;/code&gt; on &lt;code&gt;/scratch/projects&lt;/code&gt; takes 40 seconds to return. What you need is not a bigger NFS server. You need a &lt;strong&gt;parallel filesystem&lt;/strong&gt; — one that distributes both data and metadata across many servers and lets many clients read and write simultaneously without funnelling through a single gateway.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RDMA and InfiniBand From the Ground Up: Why It&#39;s Fast and How to Diagnose It</title>
      <link>/posts/rdma-and-infiniband-from-the-ground-up/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rdma-and-infiniband-from-the-ground-up/</guid>
      <description>&lt;p&gt;The first time you see an InfiniBand fabric hit its datasheet numbers — 400 Gbps of bandwidth, single-microsecond latency, zero CPU utilization on the receiving host — it feels like cheating. A 200 GbE NIC doing TCP tops out somewhere around 25 Gbps real-world throughput with one of your cores pinned at 100%. The IB NIC does 190 Gbps and the CPU barely notices. What is going on?&lt;/p&gt;&#xA;&lt;p&gt;The short answer: &lt;strong&gt;RDMA (Remote Direct Memory Access)&lt;/strong&gt; lets one machine read and write another machine&amp;rsquo;s memory directly, without involving the remote CPU, the kernel, or TCP. The longer answer — what a queue pair is, why memory registration exists, how the verbs API actually works, and how to debug fabric problems when your 400 Gbps gets you 12 — is the point of this post.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Regression at Scale: Make &#43; Jenkins &#43; SLURM for EDA Flows</title>
      <link>/posts/regression-at-scale-make-jenkins-slurm/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/regression-at-scale-make-jenkins-slurm/</guid>
      <description>&lt;p&gt;EDA flows are CI/CD problems. They just do not look like CI/CD problems at first, because the industry grew its own vocabulary — &amp;ldquo;regression,&amp;rdquo; &amp;ldquo;farm submission,&amp;rdquo; &amp;ldquo;license queue,&amp;rdquo; &amp;ldquo;turn-around time&amp;rdquo; — and because the tools involved (Synopsys, Cadence, Siemens) are a different universe from the ones that power web backends. Strip away the vocabulary, and you have the same problem every software team has: thousands of jobs, complex dependencies, flaky runs, scarce resources, and humans who need answers in the morning.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spack and EasyBuild: Reproducible HPC Software Stacks Without Losing Your Sanity</title>
      <link>/posts/spack-and-easybuild/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/spack-and-easybuild/</guid>
      <description>&lt;p&gt;There are two ways to manage scientific software on a cluster. The first is to install each package by hand: download, configure, make, &lt;code&gt;make install&lt;/code&gt;, pray that &lt;code&gt;./configure --prefix=/opt/fftw/3.3.10-gcc13&lt;/code&gt; finds the right MPI, curse when it did not, rebuild, write a module file, forget to document it, and six months later have no idea why &lt;code&gt;netcdf-fortran&lt;/code&gt; is linked against a different HDF5 than &lt;code&gt;netcdf-c&lt;/code&gt;. The second is to use a tool that treats every build as a reproducible recipe and automatically generates coherent toolchain combinations. The two dominant tools for the second approach are &lt;strong&gt;Spack&lt;/strong&gt; and &lt;strong&gt;EasyBuild&lt;/strong&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Static Timing Analysis Fundamentals: Setup, Hold, and Reading the Reports That Decide Whether Your Chip Works</title>
      <link>/posts/static-timing-analysis-fundamentals/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/static-timing-analysis-fundamentals/</guid>
      <description>&lt;p&gt;A chip that is one picosecond slow will not boot. The whole point of static timing analysis (STA) is to prove, without running a single vector through simulation, that every path in your design meets its timing — setup, hold, recovery, removal, and a handful of quieter checks — across every corner the chip must operate in. If STA passes, your chip meets timing. If STA fails and you tape out anyway, you have built a very expensive paperweight.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tcl for EDA Engineers: The Language Every Flow Script Is Secretly Written In</title>
      <link>/posts/tcl-for-eda-engineers/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tcl-for-eda-engineers/</guid>
      <description>&lt;p&gt;If you work in EDA, you write Tcl. You may not have wanted to — you may have gone into hardware to escape scripting — but Synopsys Design Compiler, PrimeTime, IC Compiler, Innovus, Genus, Tempus, Calibre, Quartus, Vivado, ModelSim, Questa, and just about every major tool exposes its command interface as a Tcl interpreter. When you type &lt;code&gt;report_timing&lt;/code&gt; or &lt;code&gt;set_max_delay 3.0 -from A -to B&lt;/code&gt;, you are typing Tcl commands. When you write a flow script that runs synthesis and then P&amp;amp;R, you are writing a Tcl program.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Verilator Deep Dive: Open-Source Simulation That Can Actually Replace Your Commercial Tool</title>
      <link>/posts/verilator-deep-dive/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/verilator-deep-dive/</guid>
      <description>&lt;p&gt;For most of its life, Verilator was &amp;ldquo;the fast open-source simulator that does not really handle SystemVerilog or testbenches.&amp;rdquo; For the last several years, that has stopped being true. Modern Verilator is a genuinely capable simulator that compiles your RTL to cycle-accurate C++ that runs 10–100× faster than event-driven commercial simulators on real workloads. It cannot do everything Questa or VCS can — no standalone UVM, limited force/release, no four-state &lt;code&gt;X&lt;/code&gt;/&lt;code&gt;Z&lt;/code&gt; by default — but the things it &lt;em&gt;does&lt;/em&gt; do, it does faster, cheaper, and with better CI story than any commercial alternative.&lt;/p&gt;</description>
    </item>
    <item>
      <title>XFS Tuning and Internals: Allocation Groups, Log Layout, and Real Workload Tuning</title>
      <link>/posts/xfs-tuning-and-internals/</link>
      <pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/xfs-tuning-and-internals/</guid>
      <description>&lt;p&gt;XFS is the quiet giant of Linux filesystems. It has been the default on RHEL since version 7, ships with petabyte-scale guarantees, and is the workhorse under most HPC parallel storage, most high-end NAS, and most large PostgreSQL installations. It does not win benchmarks with marketing; it wins them by not falling over at 3 a.m. when a 40 TB filesystem is 92% full.&lt;/p&gt;&#xA;&lt;p&gt;This post is for the engineer who has been using XFS by default for years and wants to actually understand what&amp;rsquo;s happening underneath — the allocation group architecture, the log, the tuning knobs that matter for small-file vs large-file workloads, reflinks, and the handful of pitfalls that still trip people up.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Compiling OpenAccess and OAScript on Non-RHEL Linux: A Deep Dive</title>
      <link>/posts/compiling-openaccess-oascript-non-rhel/</link>
      <pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/compiling-openaccess-oascript-non-rhel/</guid>
      <description>&lt;h1 id=&#34;compiling-openaccess-and-oascript-on-non-rhel-linux-a-deep-dive&#34;&gt;Compiling OpenAccess and OAScript on Non-RHEL Linux: A Deep Dive&lt;/h1&gt;&#xA;&lt;p&gt;The SI2 OpenAccess source distribution was developed and validated against Red Hat Enterprise Linux. RHEL and its derivatives (CentOS, Rocky Linux, AlmaLinux) are the reference platforms, the ones the Makefiles assume, and the ones where you&amp;rsquo;ll find help in the SI2 forums. If you&amp;rsquo;re working on SLES 15, Ubuntu, Debian, or any other non-RHEL distribution, you&amp;rsquo;re off the beaten path.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bend: Automatic Parallelism via Interaction Combinators</title>
      <link>/posts/bend-massively-parallel-programming/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bend-massively-parallel-programming/</guid>
      <description>&lt;p&gt;In mid-2024, a GitHub repository called Bend briefly went viral with a claim that sounded impossible: write Python-like sequential code, run it in parallel across every CPU core and GPU thread automatically, with no explicit threads, no locks, no synchronization primitives. The repo got tens of thousands of stars in days.&lt;/p&gt;&#xA;&lt;p&gt;The underlying idea is real and theoretically deep. The current implementation is research-grade. Both things are true simultaneously — and understanding why requires understanding &lt;strong&gt;interaction combinators&lt;/strong&gt;, one of the most unusual computational models you&amp;rsquo;ll encounter.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building AI Agents That Actually Work</title>
      <link>/posts/building-ai-agents-that-work/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/building-ai-agents-that-work/</guid>
      <description>&lt;p&gt;Most LLM tutorials show you how to get a model to generate text. That&amp;rsquo;s the easy part. Building an agent that reliably completes multi-step tasks, handles tool errors gracefully, doesn&amp;rsquo;t run up a $400 bill, and doesn&amp;rsquo;t get hijacked by malicious content in a web page — that&amp;rsquo;s the engineering problem nobody writes about honestly.&lt;/p&gt;&#xA;&lt;p&gt;This post covers the full stack: what agents actually are, how tool use works at the API level, structured output that doesn&amp;rsquo;t break, the ReAct loop from scratch, memory patterns for long-running agents, multi-agent coordination, and the failure modes that will bite you in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Containerization and Virtualization: Every Platform Compared</title>
      <link>/posts/containerization-and-virtualization-compared/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/containerization-and-virtualization-compared/</guid>
      <description>&lt;p&gt;&amp;ldquo;Containers vs VMs&amp;rdquo; is the wrong framing. The real question is: &lt;strong&gt;what isolation boundary do you need, for what workload, with what operational constraints?&lt;/strong&gt; The answer determines whether you want a full hypervisor, an OS-level container, a system container, a rootless container, or a specialized HPC runtime.&lt;/p&gt;&#xA;&lt;p&gt;This post maps the full landscape — every major platform, its architecture, its tradeoffs, and the workloads it&amp;rsquo;s actually suited for.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;the-taxonomy-first&#34;&gt;The Taxonomy First&lt;/h2&gt;&#xA;&lt;p&gt;Before comparing platforms, you need to understand that &amp;ldquo;virtualization&amp;rdquo; covers several fundamentally different isolation models:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Elixir and the BEAM: Concurrency That Actually Scales</title>
      <link>/posts/elixir-and-the-beam/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/elixir-and-the-beam/</guid>
      <description>&lt;p&gt;There is a class of problem that breaks most mainstream runtimes: systems that need hundreds of thousands of simultaneous long-lived connections, that must remain available under partial failure, that need to route messages between processes running on different machines, and that need to do all of this while keeping latency predictable and low. Node.js handles concurrency with a single-threaded event loop that collapses under CPU pressure. Go&amp;rsquo;s goroutines are excellent but its runtime was built for a different set of tradeoffs. Python&amp;rsquo;s GIL has been relaxed in 3.13 but it is still not a concurrency-first runtime. Ruby is beautiful but slow for concurrent work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fine-Tuning LLMs on Your Own Hardware</title>
      <link>/posts/fine-tuning-llms-on-your-own-hardware/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fine-tuning-llms-on-your-own-hardware/</guid>
      <description>&lt;h1 id=&#34;fine-tuning-llms-on-your-own-hardware&#34;&gt;Fine-Tuning LLMs on Your Own Hardware&lt;/h1&gt;&#xA;&lt;p&gt;Fine-tuning a language model used to require a cluster of A100s and a team of ML engineers. That changed with LoRA. A 7B parameter model can now be fine-tuned on a single consumer GPU with 16 GB of VRAM in an afternoon. A 70B model fits on a single A100 with QLoRA quantization. The techniques are mature, the tooling is excellent, and the results are production-quality.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Gleam: Type Safety on the BEAM</title>
      <link>/posts/gleam-type-safe-beam-language/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gleam-type-safe-beam-language/</guid>
      <description>&lt;p&gt;The Erlang VM has a deserved reputation for indestructibility. WhatsApp ran on it at two billion users. Ericsson built the AXD301 switch — nine-nines uptime — on it in the 1990s. The BEAM&amp;rsquo;s preemptive scheduler, per-process garbage collection, and actor-model concurrency represent decades of hard-won production wisdom that no new runtime is going to replicate overnight.&lt;/p&gt;&#xA;&lt;p&gt;The price of admission has always been a dynamic type system. Erlang and Elixir are expressive, powerful languages, but the feedback loop is runtime-first: dialyzer helps, but it&amp;rsquo;s opt-in, post-hoc analysis, not a compiler that refuses to produce a binary until your types make sense. Teams that want the BEAM&amp;rsquo;s legendary fault tolerance but also want a type system that catches the class of errors that crash production services at 3 AM have historically had no good answer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GPU Programming Without CUDA: OpenCL, ROCm, Vulkan, Metal, and WebGPU</title>
      <link>/posts/gpu-programming-without-cuda/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gpu-programming-without-cuda/</guid>
      <description>&lt;h1 id=&#34;gpu-programming-without-cuda-opencl-rocm-vulkan-metal-and-webgpu&#34;&gt;GPU Programming Without CUDA: OpenCL, ROCm, Vulkan, Metal, and WebGPU&lt;/h1&gt;&#xA;&lt;p&gt;CUDA is the dominant GPU compute platform, and for good reason — NVIDIA&amp;rsquo;s toolchain, libraries (cuBLAS, cuDNN, NCCL), and ecosystem are genuinely excellent. But CUDA only runs on NVIDIA hardware. If you&amp;rsquo;re targeting AMD GPUs, Apple Silicon, Intel Arc, mobile devices, or the browser, you need something else.&lt;/p&gt;&#xA;&lt;p&gt;This post covers the full non-CUDA landscape: what each platform is, what hardware it targets, where it excels, and enough working code to understand the programming model. We&amp;rsquo;ll also cover abstraction layers that let you write once and run on multiple backends.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Memory Management Deep Dive</title>
      <link>/posts/linux-memory-management-deep-dive/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-memory-management-deep-dive/</guid>
      <description>&lt;h1 id=&#34;linux-memory-management-deep-dive&#34;&gt;Linux Memory Management Deep Dive&lt;/h1&gt;&#xA;&lt;p&gt;Memory management is one of those kernel subsystems that most engineers interact with only when something goes wrong — an OOM kill, a mysterious slowdown, a latency spike that correlates with nothing obvious. Understanding how Linux manages memory doesn&amp;rsquo;t just help you debug these situations; it changes how you architect systems in the first place.&lt;/p&gt;&#xA;&lt;p&gt;This post covers the full stack: virtual memory fundamentals, the page allocator, huge pages (transparent and explicit), NUMA topology, the OOM killer, and the tools for measuring and tuning memory behavior.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nix Flakes: Reproducible Development Environments Done Right</title>
      <link>/posts/nix-flakes-reproducible-environments/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nix-flakes-reproducible-environments/</guid>
      <description>&lt;p&gt;If you have spent any time with Nix, you have probably heard two things in the same breath: &amp;ldquo;Nix is incredibly powerful&amp;rdquo; and &amp;ldquo;Nix is incredibly confusing.&amp;rdquo; The classic Nix experience involves &lt;code&gt;nix-channel&lt;/code&gt; commands that modify global state, a &lt;code&gt;NIX_PATH&lt;/code&gt; environment variable that varies between machines, and &lt;code&gt;default.nix&lt;/code&gt; files with no standard schema. You could write a perfectly good Nix expression and still get different results on two machines because they had different channels pinned.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Odin: Data-Oriented Systems Programming</title>
      <link>/posts/odin-data-oriented-systems-programming/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/odin-data-oriented-systems-programming/</guid>
      <description>&lt;p&gt;Systems programming has a problem that no one wants to admit: the tooling got too clever. C++ grew operator overloading, exceptions, template metaprogramming, and virtual dispatch until reading a line of code required three layers of indirection to understand what actually happens at the machine level. Rust added safety guarantees that genuinely matter, but brought lifetimes, the borrow checker, and a complexity budget that many programmers find exhausting for projects that just need fast, simple, predictable code. Go went the other way — safe and simple but garbage-collected and not suitable for low-level systems work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Security Hardening: A Practical Guide</title>
      <link>/posts/postgresql-security-hardening/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/postgresql-security-hardening/</guid>
      <description>&lt;h1 id=&#34;postgresql-security-hardening-a-practical-guide&#34;&gt;PostgreSQL Security Hardening: A Practical Guide&lt;/h1&gt;&#xA;&lt;p&gt;PostgreSQL ships with a permissive default configuration designed for ease of development, not production security. The &lt;code&gt;postgres&lt;/code&gt; superuser has no password. &lt;code&gt;pg_hba.conf&lt;/code&gt; trusts local connections by default. SSL is disabled in many distributions. And most applications connect with more privileges than they need.&lt;/p&gt;&#xA;&lt;p&gt;This guide walks through a complete security hardening process: authentication, network security, TLS, roles and least privilege, row-level security, auditing, and secret rotation with Vault. The goal is a PostgreSQL instance that&amp;rsquo;s defensible at every layer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox &#43; Ceph: Hyperconverged Storage Deep Dive</title>
      <link>/posts/proxmox-ceph-hyperconverged-storage/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-ceph-hyperconverged-storage/</guid>
      <description>&lt;h1 id=&#34;proxmox--ceph-hyperconverged-storage-deep-dive&#34;&gt;Proxmox + Ceph: Hyperconverged Storage Deep Dive&lt;/h1&gt;&#xA;&lt;p&gt;Hyperconverged infrastructure (HCI) collapses separate compute and storage servers into a single cluster where every node contributes both CPU/RAM for VMs and disk capacity to a shared storage pool. Proxmox VE with Ceph is the leading open-source HCI stack — and unlike commercial alternatives (Nutanix, VMware vSAN), it runs on commodity hardware with no per-socket licensing.&lt;/p&gt;&#xA;&lt;p&gt;This guide goes deep: how Ceph works internally, how to make correct design decisions before the first disk is formatted, how to tune for SSDs versus spinning disks, and how to operate the cluster reliably in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox Backup Server In Depth</title>
      <link>/posts/proxmox-backup-server-in-depth/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-backup-server-in-depth/</guid>
      <description>&lt;h1 id=&#34;proxmox-backup-server-in-depth&#34;&gt;Proxmox Backup Server In Depth&lt;/h1&gt;&#xA;&lt;p&gt;Proxmox Backup Server (PBS) is a dedicated backup solution designed specifically for Proxmox VE environments. Unlike generic backup tools bolted onto a hypervisor, PBS was built from the ground up around the specific characteristics of VM and container backups: large, structured disk images that change incrementally between snapshots.&lt;/p&gt;&#xA;&lt;p&gt;The result is a backup system with genuinely impressive efficiency: incremental forever backups, client-side deduplication across all backups in a datastore, optional end-to-end encryption, and a verification system that continuously validates backup integrity. This post covers how it works internally, how to operate it at scale, and how to build a resilient multi-site backup architecture.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox for SMB: Migrating from VMware</title>
      <link>/posts/proxmox-for-smb-migrating-from-vmware/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-for-smb-migrating-from-vmware/</guid>
      <description>&lt;h1 id=&#34;proxmox-for-smb-migrating-from-vmware&#34;&gt;Proxmox for SMB: Migrating from VMware&lt;/h1&gt;&#xA;&lt;p&gt;Broadcom&amp;rsquo;s acquisition of VMware in 2023 set off one of the largest infrastructure migration waves the SMB market has seen in years. Licensing costs increased dramatically, perpetual licenses disappeared in favor of subscriptions, and reseller support channels were restructured in ways that left many small and medium businesses effectively without a viable path forward on their existing agreements.&lt;/p&gt;&#xA;&lt;p&gt;Proxmox VE has emerged as the leading open-source alternative — and for good reason. It&amp;rsquo;s production-grade, actively developed, runs on standard x86 hardware, has a strong community, and offers enterprise support subscriptions at a fraction of VMware&amp;rsquo;s new pricing. This guide is written for the IT administrator or infrastructure engineer at a 10–500 person company who needs to migrate a VMware environment to Proxmox without the luxury of a dedicated migration team.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox SDN: Software Defined Networking</title>
      <link>/posts/proxmox-sdn-software-defined-networking/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-sdn-software-defined-networking/</guid>
      <description>&lt;h1 id=&#34;proxmox-sdn-software-defined-networking&#34;&gt;Proxmox SDN: Software Defined Networking&lt;/h1&gt;&#xA;&lt;p&gt;Traditional Proxmox networking uses Linux bridges configured per-node. This works for small setups, but as clusters grow you hit real limitations: network config must be manually replicated across nodes, VLANs require physical switch configuration, and there&amp;rsquo;s no built-in way to create isolated tenant networks that span nodes without pre-provisioning them on every host.&lt;/p&gt;&#xA;&lt;p&gt;Proxmox SDN (introduced as stable in PVE 8.1) solves this with a cluster-wide networking abstraction. You define networks once in the datacenter-level configuration and Proxmox propagates them to all nodes automatically. More importantly, it supports VXLAN and EVPN overlay networks that let you create virtual L2 segments spanning the entire cluster without touching your physical switches.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Roc: Functional Programming Without the Complexity Tax</title>
      <link>/posts/roc-functional-without-the-baggage/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/roc-functional-without-the-baggage/</guid>
      <description>&lt;p&gt;There is a recurring pattern in functional programming adoption: an engineer hears about Elm or Haskell, gets excited about the guarantees, opens the documentation, and then backs away slowly. Elm is friendly but browser-only and opinionated to the point of frustration. Haskell is powerful but arrives with a 30-year accumulation of concepts — monads, typeclasses, monad transformers, GADTs, rank-N types — that you need to understand before you can read a moderately serious codebase. OCaml and F# split the difference but come with their own runtime baggage and ecosystem assumptions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SLOs in Practice: Beyond the Math</title>
      <link>/posts/slos-in-practice-beyond-the-math/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/slos-in-practice-beyond-the-math/</guid>
      <description>&lt;h1 id=&#34;slos-in-practice-beyond-the-math&#34;&gt;SLOs in Practice: Beyond the Math&lt;/h1&gt;&#xA;&lt;p&gt;The SLO conversation in most organizations goes one of two ways. Either it stays theoretical — engineers understand the concepts, there are some dashboards, but nobody actually changes behavior based on the error budget. Or it gets implemented too rigidly, producing alert fatigue and resentment because the numbers don&amp;rsquo;t reflect what users actually experience.&lt;/p&gt;&#xA;&lt;p&gt;Getting SLOs to work requires more than correct math. It requires alert designs that page at the right time, error budget policies that have teeth, tooling that keeps the overhead low, and — hardest of all — organizational buy-in that makes the whole thing worth doing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The WASI Component Model: WebAssembly&#39;s Missing Piece</title>
      <link>/posts/wasi-component-model/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wasi-component-model/</guid>
      <description>&lt;p&gt;WebAssembly modules are islands. Each one gets a flat block of linear memory — bytes with addresses. When you want to call a function in another module, you pass integers and floats. You want to send a string? Pass a pointer (an integer) and a length (another integer) and hope both sides agree on the encoding. Want to return a list of structs? Better have a memory-allocation protocol documented somewhere. In practice, this worked well enough for browser use cases — JS held everything together. But for server-side polyglot architectures, it was a fundamental blocker.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Traefik as a Kubernetes Ingress Controller: The Complete Guide</title>
      <link>/posts/traefik-kubernetes-ingress/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/traefik-kubernetes-ingress/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;/posts/traefik-complete-guide/&#34;&gt;Traefik complete guide&lt;/a&gt; covers Docker integration, Let&amp;rsquo;s Encrypt, the middleware ecosystem, and touches on Kubernetes. This post goes much deeper on the Kubernetes-specific story. It assumes you are already comfortable with Kubernetes fundamentals — pods, services, namespaces, RBAC, Helm — and want to understand how to run Traefik in a cluster &lt;em&gt;properly&lt;/em&gt;, at production quality.&lt;/p&gt;&#xA;&lt;p&gt;By the end you will have a clear mental model of how Traefik integrates with the Kubernetes API, why its CRDs are more expressive than standard &lt;code&gt;Ingress&lt;/code&gt; resources, how to handle TLS with cert-manager, how to lock down RBAC, how to run multiple replicas without certificate-storage conflicts, and how to wire up real observability.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Carbon: Google&#39;s Bet on a C&#43;&#43; Successor</title>
      <link>/posts/carbon-googles-cpp-successor/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/carbon-googles-cpp-successor/</guid>
      <description>&lt;p&gt;C++ has survived 40 years of engineering criticism, countless &amp;ldquo;replacement&amp;rdquo; attempts, and the relentless rise of memory-safe languages. It is still the dominant language for systems programming, game engines, embedded firmware, compilers, and high-frequency trading infrastructure. If you write performance-critical code for a living, you likely live in C++.&lt;/p&gt;&#xA;&lt;p&gt;In July 2022, Chandler Carruth stepped onto the stage at CppNorth and announced Carbon — not another language that wants to replace C++, but a &amp;ldquo;successor language&amp;rdquo; designed to interoperate deeply with existing C++ codebases while offering the kind of ergonomics and safety guarantees that C++ simply cannot retrofit onto itself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Crystal: Ruby Syntax, C Speed</title>
      <link>/posts/crystal-ruby-syntax-c-speed/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/crystal-ruby-syntax-c-speed/</guid>
      <description>&lt;p&gt;Crystal is not &amp;ldquo;Ruby but fast.&amp;rdquo; That framing undersells it and misleads newcomers. Crystal is a statically typed, compiled language that borrows Ruby&amp;rsquo;s syntax and idioms to the extent that large chunks of Crystal code are valid Ruby and vice versa — but underneath it produces native binaries via LLVM, performs type inference across your entire program at compile time, and offers a macro system that operates on the AST rather than through string substitution.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Haskell: Pure Functional Programming in Practice</title>
      <link>/posts/haskell-pure-functional-programming/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/haskell-pure-functional-programming/</guid>
      <description>&lt;p&gt;Haskell is the language that programmers argue about on the internet and quietly respect in private. It has influenced the design of virtually every typed functional language built in the last twenty years — Scala&amp;rsquo;s type classes, Rust&amp;rsquo;s traits, Swift&amp;rsquo;s protocol extensions, and F#&amp;rsquo;s computation expressions all trace lineage to ideas Haskell formalized or popularized. Yet Haskell itself remains a niche production language, used seriously in finance, compilers, and correctness-critical infrastructure but absent from most job descriptions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Julia: High-Performance Scientific Computing</title>
      <link>/posts/julia-high-performance-scientific-computing/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/julia-high-performance-scientific-computing/</guid>
      <description>&lt;h1 id=&#34;julia-high-performance-scientific-computing&#34;&gt;Julia: High-Performance Scientific Computing&lt;/h1&gt;&#xA;&lt;p&gt;For most numerical work, scientists and engineers live in a two-language world. You prototype in Python or R because the ecosystem is rich, the syntax is expressive, and iteration is fast. Then, when performance matters — the simulation that takes 8 hours in NumPy, the ODE solver that needs to run millions of times, the Monte Carlo sampler bottlenecked in pure Python — you rewrite the hot path in C, C++, or Fortran, wrap it with ctypes or f2py, and accept the cognitive overhead of maintaining two codebases in two languages with a FFI seam between them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lua: The Embeddable Language</title>
      <link>/posts/lua-the-embeddable-language/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/lua-the-embeddable-language/</guid>
      <description>&lt;p&gt;Lua is one of the most widely deployed programming languages you&amp;rsquo;ve probably never written production code in directly. It runs inside nginx via OpenResty (powering Kong API Gateway, Cloudflare&amp;rsquo;s edge, and countless WAFs), inside Redis as an atomic scripting engine, inside Neovim replacing Vimscript, inside World of Warcraft&amp;rsquo;s entire addon system, inside Roblox serving 70+ million daily active users, and inside dozens of game engines from small indie frameworks to AAA titles. It does all of this from a codebase that compiles to under 300KB.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mojo: Python Syntax, Metal-Level Performance</title>
      <link>/posts/mojo-python-with-superpowers/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mojo-python-with-superpowers/</guid>
      <description>&lt;p&gt;There is a recurring tension in AI and ML engineering: Python is the lingua franca of the entire field, but Python is slow. Not &amp;ldquo;a bit slow&amp;rdquo; — orders of magnitude slow for numerical kernels. The entire NumPy/SciPy/PyTorch ecosystem exists as a layer of C, C++, and CUDA wrapping a Python interface, because doing the actual math in pure Python would be comically impractical. Every time you call &lt;code&gt;np.matmul&lt;/code&gt;, you dive out of Python into a Fortran BLAS routine. Every time you run a PyTorch autograd pass, you&amp;rsquo;re in C++.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nim: Efficient, Expressive, and Underrated</title>
      <link>/posts/nim-efficient-and-expressive/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nim-efficient-and-expressive/</guid>
      <description>&lt;p&gt;There is a language that gives you Python&amp;rsquo;s syntax, C&amp;rsquo;s performance, Lisp&amp;rsquo;s macro power, and Rust-quality binary output — all in a single compiler with no runtime dependency. Most engineers have never used it. Some have never heard of it. That language is Nim.&lt;/p&gt;&#xA;&lt;p&gt;Nim is not a research project or a toy. It compiles to C, C++, or JavaScript. The resulting binaries are small, fast, and have no dependency on a Nim runtime. It has shipped in production at companies like Status (the Ethereum client), in the game engine Godot (via GDScript&amp;rsquo;s design influence), in network tools, CLI utilities, and embedded systems. Nim 2.0 shipped in 2023, marking the language&amp;rsquo;s first major stability milestone — breaking changes are no longer on the table without strong justification.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Perl: Still Powering the World&#39;s Sysadmin Scripts</title>
      <link>/posts/perl-the-sysadmin-powerhouse/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/perl-the-sysadmin-powerhouse/</guid>
      <description>&lt;p&gt;Perl is the language you inherit. You join a team, open the infrastructure repo, and somewhere in &lt;code&gt;scripts/&lt;/code&gt; there are three thousand lines of Perl that parse router configs, aggregate logs, and generate compliance reports. They&amp;rsquo;ve run reliably every night for fifteen years. Nobody wants to touch them. Nobody can quite explain all of them. But they work.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s the Perl reality in 2026. Not dead. Not irrelevant. But certainly not what it was in 2001, when it was the glue language of choice for the entire internet. Understanding what Perl still does well — and being honest about where it doesn&amp;rsquo;t — is genuinely useful for any engineer who operates production infrastructure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>R for Data Analysis: A Practical Guide for Engineers</title>
      <link>/posts/r-for-data-analysis/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/r-for-data-analysis/</guid>
      <description>&lt;p&gt;You already know Python. You can wrangle a DataFrame, fit a scikit-learn model, and ship something to production. So why would you spend time learning R?&lt;/p&gt;&#xA;&lt;p&gt;The honest answer is: you might not need to. If your job is building ML pipelines, APIs, or data products that need to live on servers somewhere, Python is the right choice. But if you are doing serious statistical modeling, working in academia, pharma, bioinformatics, or producing publication-quality visualizations, R is the better tool — not because of ecosystem inertia, but because it was designed from the ground up for this specific work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>V: Fast Compilation and Simple Systems Programming</title>
      <link>/posts/v-lang-simple-and-fast/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/v-lang-simple-and-fast/</guid>
      <description>&lt;p&gt;V is a statically typed, compiled language designed around three ideas: extreme simplicity, sub-second compilation, and memory safety without a borrow checker. Created by Alexander Medvednikov and first announced publicly in 2019, V generated enormous enthusiasm — and equally enormous controversy. The original claims were breathtaking: no null, no global variables, autofree memory management, a massive standard library, hot code reloading, a built-in ORM, cross-compilation to every major platform, and compilation speeds of 1.2 million lines per second. Some of those claims were real. Some were aspirational. Some were frankly not true at the time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zig: The Modern C Replacement</title>
      <link>/posts/zig-the-modern-c-replacement/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zig-the-modern-c-replacement/</guid>
      <description>&lt;p&gt;C has been the language of systems programming for over fifty years. It is also a language with undefined behavior lurking around nearly every corner: signed integer overflow is UB, reading uninitialized memory is UB, a pointer cast that violates strict aliasing is UB, a union member access outside the active member is UB. The compiler is allowed to assume none of these things happen, which means when they do, the results are not &amp;ldquo;wrong output&amp;rdquo; but rather &amp;ldquo;the compiler deleted your security check because it proved it was unreachable.&amp;rdquo; The CVE databases are a monument to this bargain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>10 Tech YouTubers Actually Worth Your Time</title>
      <link>/posts/top-tech-youtubers/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/top-tech-youtubers/</guid>
      <description>&lt;p&gt;YouTube&amp;rsquo;s tech content has a signal-to-noise problem. For every creator doing original, technically rigorous work, there are twenty channels running AI-generated voiceovers over stock footage, recycling the same &amp;ldquo;top 10 Linux commands&amp;rdquo; video for the fourth time, or padding out 6-minute topics into 20-minute videos with sponsor reads and &amp;ldquo;smash that like button&amp;rdquo; filler.&lt;/p&gt;&#xA;&lt;p&gt;The channels below are the ones that don&amp;rsquo;t do that. They&amp;rsquo;re the creators who clearly know what they&amp;rsquo;re talking about, put real time into their content, and treat their audience as intelligent adults. The focus is on homelab, AI, networking, and DevOps topics — long-form content preferred. If you already watch NetworkChuck and want more of that caliber, these are the places to go next.&lt;/p&gt;</description>
    </item>
    <item>
      <title>C# and .NET for Backend Engineers</title>
      <link>/posts/csharp-dotnet-for-backend-engineers/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/csharp-dotnet-for-backend-engineers/</guid>
      <description>&lt;p&gt;.NET has a perception problem similar to Java&amp;rsquo;s. Developers who last encountered it in the mid-2000s remember Windows-only deployment, expensive Visual Studio licenses, and COM interop nightmares. Since Microsoft open-sourced the platform in 2016 and rebuilt it from scratch as .NET Core (now just .NET), that world no longer exists.&lt;/p&gt;&#xA;&lt;p&gt;Today&amp;rsquo;s .NET runs natively on Linux and macOS, ships as single self-contained binaries, compiles ahead-of-time to native code with sub-100ms startup times, and consistently ranks at the top of the TechEmpower benchmarks. ASP.NET Core reached 27.5 million requests per second in Round 23 plaintext tests. If you haven&amp;rsquo;t looked at it since the .NET Framework era, you&amp;rsquo;re working with a decade-old mental model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chicken Scheme: A Practical Guide for Systems Engineers</title>
      <link>/posts/chicken-scheme-practical-guide/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/chicken-scheme-practical-guide/</guid>
      <description>&lt;p&gt;Scheme is a language that has been quietly doing serious work for decades. It is the language SICP was written in. Naughty Dog used a Racket-derived Scheme as the scripting engine for Uncharted and The Last of Us. GNU Guile is the official extension language of the GNU project. And CHICKEN Scheme — the subject of this guide — compiles your Scheme to portable C, producing standalone native binaries that run on Linux, macOS, Windows, ARM, MIPS, SPARC64, and anything else with a C toolchain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deterministic and Reproducible Builds: Why Your Build Should Be a Pure Function</title>
      <link>/posts/deterministic-reproducible-builds/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/deterministic-reproducible-builds/</guid>
      <description>&lt;h1 id=&#34;deterministic-and-reproducible-builds-why-your-build-should-be-a-pure-function&#34;&gt;Deterministic and Reproducible Builds: Why Your Build Should Be a Pure Function&lt;/h1&gt;&#xA;&lt;p&gt;A build is a function. It takes source code as input and produces artifacts as output. Like any function, the question is: given the same inputs, does it always produce the same output?&lt;/p&gt;&#xA;&lt;p&gt;For most software projects, the answer is no. Run a build twice on different machines, or on the same machine a week apart, and you&amp;rsquo;ll likely get different bytes in your output — different embedded timestamps, different tool versions, different ordering of symbols resolved by the linker. Most of the time this doesn&amp;rsquo;t matter. Sometimes it matters enormously.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Go for Systems and Backend Development</title>
      <link>/posts/go-for-systems-and-backend/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/go-for-systems-and-backend/</guid>
      <description>&lt;p&gt;Go is the language of cloud-native infrastructure. Kubernetes, Docker, Terraform, Prometheus, etcd, Consul, Hugo, the GitHub CLI—all written in Go. If you work in modern infrastructure, you read Go regularly whether you intend to or not. Learning to write it well is one of the highest-leverage investments an ops engineer or backend developer can make.&lt;/p&gt;&#xA;&lt;p&gt;This isn&amp;rsquo;t a &amp;ldquo;Hello, World&amp;rdquo; tutorial. It covers the parts of Go that actually matter for writing reliable systems: the concurrency model, error handling patterns, standard library depth, and practical tooling for building CLIs and HTTP services.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google&#39;s TurboQuant: What It Means for Home AI Enthusiasts</title>
      <link>/posts/google-turboquant-what-it-means-for-home-users/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/google-turboquant-what-it-means-for-home-users/</guid>
      <description>&lt;p&gt;On March 25, 2026, Google Research published a blog post announcing &lt;strong&gt;TurboQuant&lt;/strong&gt;, a vector quantization algorithm that reduces the memory footprint of LLM KV caches by up to 6x — without retraining, and with claimed zero accuracy loss. Memory chip stocks (Micron, Western Digital) took immediate hits. The local AI community went into overdrive.&lt;/p&gt;&#xA;&lt;p&gt;Two weeks later, community implementations exist, real-world benchmarks are in, framework PRs are actively developing, and a genuine academic controversy has emerged. Here&amp;rsquo;s the full picture.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java in 2026: Still Relevant</title>
      <link>/posts/java-in-2026/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/java-in-2026/</guid>
      <description>&lt;p&gt;Java has a reputation problem. Developers who last used it in 2010 remember verbose getters and setters, XML-heavy Spring configuration, and threads that consumed megabytes of memory each. They moved on to Python, Go, or Node.js and never looked back.&lt;/p&gt;&#xA;&lt;p&gt;That Java is gone. The language that ships in 2026 has records, sealed classes, pattern matching, and virtual threads capable of handling millions of concurrent connections with blocking code. GraalVM compiles it to native binaries that start in under 100ms and use 50MB of memory. The six-month release cadence that Java adopted in 2018 has delivered more innovation in the last five years than in the prior decade.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kotlin for JVM and Beyond</title>
      <link>/posts/kotlin-for-jvm-and-beyond/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kotlin-for-jvm-and-beyond/</guid>
      <description>&lt;p&gt;Kotlin hit 1.0 in 2016, became Google&amp;rsquo;s preferred Android language in 2017, and has spent the years since quietly taking over large swaths of the JVM ecosystem. Today, with the K2 compiler stable, Kotlin Multiplatform shipping production code to iOS, and coroutines adopted by every major async framework, Kotlin is no longer &amp;ldquo;better Java&amp;rdquo;—it&amp;rsquo;s a serious contender for any project that touches the JVM or needs to share logic across platforms.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Managing a Fleet of Personal Machines Without Losing Your Mind</title>
      <link>/posts/managing-multiple-machines/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/managing-multiple-machines/</guid>
      <description>&lt;p&gt;There&amp;rsquo;s a specific kind of person reading this post. You have several computers. Maybe a desktop, a couple of laptops, a few Raspberry Pis, a NAS, some repurposed thinkpads running various things. You got each one for a reason that made sense at the time. And now you spend a non-trivial amount of your free time applying updates, fixing things that broke, and occasionally wondering whether any of this is actually worth it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenAccess and OAScript: The Open EDA Database Standard</title>
      <link>/posts/openaccess-oascript-eda-database/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/openaccess-oascript-eda-database/</guid>
      <description>&lt;p&gt;If you work in IC design automation, physical design, or EDA tool development, you have almost certainly touched OpenAccess data — quite possibly without knowing it. Cadence Virtuoso, every major place-and-route tool, and dozens of commercial and open-source utilities either read from or write to OpenAccess databases. Understanding the database standard itself, and knowing how to drive it programmatically with OAScript, makes you significantly more effective at building flows, debugging data problems, and writing design automation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PHP: The Comeback Kid</title>
      <link>/posts/php-the-comeback-kid/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/php-the-comeback-kid/</guid>
      <description>&lt;p&gt;PHP is the language everyone has an opinion about and most people stopped evaluating a decade ago. The criticisms of 2012-era PHP—inconsistent function signatures, no types, &lt;code&gt;register_globals&lt;/code&gt;, magic quotes—were valid. The language earned its reputation.&lt;/p&gt;&#xA;&lt;p&gt;Then it changed. PHP 7 added scalar type declarations and killed the performance gap with Python. PHP 8.0 added JIT compilation, union types, named arguments, and match expressions. PHP 8.1 introduced enums and fibers. PHP 8.4 shipped property hooks and asymmetric visibility. Laravel went from a scrappy Rails clone to the dominant web framework. The language that developers dismissed quietly powered 79% of the web the whole time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ruby: The Language That Still Ships</title>
      <link>/posts/ruby-the-language-that-still-ships/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ruby-the-language-that-still-ships/</guid>
      <description>&lt;p&gt;Ruby has been declared dead so many times that the community stopped counting. Node.js was going to kill it. Go was going to kill it. Python&amp;rsquo;s explosion in ML was going to kill it. The shift to microservices was going to kill it.&lt;/p&gt;&#xA;&lt;p&gt;Shopify still runs the largest Rails app in the world. GitHub deploys a two-million-line Rails monolith twenty times a day. Stripe powers global fintech on Ruby. Basecamp is still building product on the framework it created. The language that was supposed to die keeps shipping.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Scala: Functional Programming on the JVM</title>
      <link>/posts/scala-functional-programming-jvm/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/scala-functional-programming-jvm/</guid>
      <description>&lt;p&gt;Scala has been polarizing since its first public release in 2004. It promised the best of both worlds — object-oriented and functional programming on the JVM — and in doing so delivered a language so expressive that it could solve problems elegantly, and so complex that it could destroy productivity. The Scala 3 release (formerly Dotty) represents a serious attempt to reckon with that complexity: a complete redesign of the type system foundations, a cleaner syntax, and a principled replacement of the most notoriously confusing feature in the language — implicits.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Swift on the Server: A Technical Deep Dive for Experienced Engineers</title>
      <link>/posts/swift-on-the-server/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/swift-on-the-server/</guid>
      <description>&lt;p&gt;Swift has spent most of its public life associated with Xcode, iOS simulators, and the App Store. That reputation is outdated. Swift runs on Linux without Apple frameworks. It powers production servers at Apple, handles real-time sync for Things Cloud, and runs inside AWS Lambda functions compiled to native ARM64 binaries. Swift 6.0 — released in September 2024 — introduced compile-time data race safety that Go and Python don&amp;rsquo;t attempt and Rust achieves only through a harder-to-learn ownership model. There is an active SSWG (Swift Server Workgroup) maintaining a production-grade ecosystem of networking, database, and observability libraries.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Modern Terminal Stack: A Complete CLI Upgrade Guide</title>
      <link>/posts/modern-terminal-stack/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/modern-terminal-stack/</guid>
      <description>&lt;h1 id=&#34;the-modern-terminal-stack-a-complete-cli-upgrade-guide&#34;&gt;The Modern Terminal Stack: A Complete CLI Upgrade Guide&lt;/h1&gt;&#xA;&lt;p&gt;The terminal is where engineers live. And yet most of us spend years using a setup that hasn&amp;rsquo;t changed much since the 1990s — a bare &lt;code&gt;bash&lt;/code&gt; prompt, &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt;, and maybe a &lt;code&gt;.bashrc&lt;/code&gt; with a few aliases. The tooling ecosystem has quietly undergone a renaissance. There are now faster, smarter, and more ergonomic replacements for nearly every core Unix utility, plus entirely new categories of tools that didn&amp;rsquo;t exist before.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TypeScript Deep Dive</title>
      <link>/posts/typescript-deep-dive/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/typescript-deep-dive/</guid>
      <description>&lt;p&gt;TypeScript has won. What started as a Microsoft project in 2012 now powers Slack, Airbnb, Stripe, and effectively the entire Node.js backend ecosystem. Vue 3 was rewritten in TypeScript. Angular was built on it from day one. Even plain JavaScript projects routinely use TypeScript for editor intelligence via JSDoc. If you write serious JavaScript today and aren&amp;rsquo;t using TypeScript, you&amp;rsquo;re working against the grain.&lt;/p&gt;&#xA;&lt;p&gt;This isn&amp;rsquo;t a beginner&amp;rsquo;s guide. It assumes you know JavaScript and at least one typed language. The goal is to explain the parts of TypeScript that actually matter—the type system features that take work to understand but pay back every day.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing CLI Tools with Great UX: The Complete Guide</title>
      <link>/posts/writing-cli-tools-with-great-ux/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/writing-cli-tools-with-great-ux/</guid>
      <description>&lt;h1 id=&#34;writing-cli-tools-with-great-ux-the-complete-guide&#34;&gt;Writing CLI Tools with Great UX: The Complete Guide&lt;/h1&gt;&#xA;&lt;p&gt;A CLI tool is a user interface. The user is a developer, the interface is text, and the medium is a terminal. But the fundamental design problem — how do you make something easy and pleasant to use? — is the same as for any other interface.&lt;/p&gt;&#xA;&lt;p&gt;Most CLI tools fail not because they lack features, but because they ignore the conventions and ergonomics that make tools feel native to the terminal. This guide covers the full stack: API design, argument parsing, output formatting, configuration, shell completions, and distribution.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Perses: The Open Dashboarding Standard</title>
      <link>/posts/perses-open-dashboarding-standard/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/perses-open-dashboarding-standard/</guid>
      <description>&lt;p&gt;Dashboards have always been the odd exception in infrastructure-as-code. Your Terraform is in Git. Your Kubernetes manifests are in Git. Your CI/CD pipelines are in Git. But your Grafana dashboards? Probably clicked together in the UI and exported as opaque JSON blobs that nobody really reviews or versions properly.&lt;/p&gt;&#xA;&lt;p&gt;Perses was built to fix this. It&amp;rsquo;s an open-source dashboarding platform — CNCF sandbox since August 2024 — that treats dashboards as first-class code artifacts. Dashboards are defined in YAML or Go, validated by a schema, linted in CI, and deployed through GitOps workflows. In Kubernetes, they&amp;rsquo;re CRDs. In your repo, they&amp;rsquo;re files next to the rest of your infrastructure code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Port: The Internal Developer Portal That Works Out of the Box</title>
      <link>/posts/port-internal-developer-portal/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/port-internal-developer-portal/</guid>
      <description>&lt;p&gt;Port is an internal developer portal (IDP) built as a product rather than a framework. Where Backstage hands you a pile of React components and says &amp;ldquo;good luck,&amp;rdquo; Port hands you a working portal on day one. You model your engineering world through a flexible data model, connect your tools, and expose self-service actions — all through a UI or API, without writing and deploying custom code.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers everything a platform engineer needs to evaluate, deploy, and extend Port: the data model, blueprint system, integrations, self-service actions, scorecards, the Ocean framework, and how it honestly stacks up against Backstage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pyroscope: Continuous Profiling in Production</title>
      <link>/posts/pyroscope-continuous-profiling/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pyroscope-continuous-profiling/</guid>
      <description>&lt;p&gt;Metrics tell you something is slow. Traces tell you where in the request the slowness happened. But neither tells you &lt;em&gt;why&lt;/em&gt; the code in that span is slow — which function is burning CPU, where memory is leaking, which lock is causing contention. That&amp;rsquo;s what profiling is for.&lt;/p&gt;&#xA;&lt;p&gt;The traditional approach is on-demand profiling: trigger a pprof capture when something goes wrong, stare at the flame graph, try to reproduce the problem. This works for obvious bugs in development but fails in production, where the worst issues are transient, non-reproducible under artificial load, or only visible at specific traffic patterns.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Python for DevOps and Automation</title>
      <link>/posts/python-for-devops/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/python-for-devops/</guid>
      <description>&lt;p&gt;Python is the lingua franca of DevOps. Not because it&amp;rsquo;s the fastest language or the most elegant, but because it sits at the intersection of readable, powerful, and universally available. Ansible is written in Python. The AWS, GCP, and Azure SDKs all have first-class Python support. Most observability tooling either runs on Python or provides Python clients first. Kubernetes operators are increasingly written in Python using frameworks like Kopf. If you&amp;rsquo;re working in ops, you will write Python.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Radius: Microsoft&#39;s Open-Source Application Platform for Cloud-Native Teams</title>
      <link>/posts/radius-cloud-native-application-platform/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/radius-cloud-native-application-platform/</guid>
      <description>&lt;p&gt;Platform engineering has a recurring problem: the gap between what developers want (self-service infrastructure, consistent environments, no cloud-specific knowledge required) and what platform teams can deliver (compliant, secure, cost-controlled infrastructure that follows organizational policy). Kubernetes made deploying containers easier, but it widened that gap — every developer now needs to understand Deployments, Services, Ingresses, ConfigMaps, secrets, namespace hygiene, and cloud-specific integrations just to run an application.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Radius&lt;/strong&gt; is Microsoft&amp;rsquo;s attempt to close that gap with a different abstraction layer. Rather than making Kubernetes easier to use, Radius adds an application-centric model on top of it: developers describe &lt;em&gt;what&lt;/em&gt; their application needs (a container, a Redis cache, a message queue), platform teams describe &lt;em&gt;how&lt;/em&gt; those needs are implemented in each environment (Terraform modules, Bicep templates, cloud-specific configurations), and Radius wires them together at deploy time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Score: Developer-Centric Workload Specification</title>
      <link>/posts/score-workload-specification/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/score-workload-specification/</guid>
      <description>&lt;p&gt;Here&amp;rsquo;s a configuration problem most teams hit eventually: you have a &lt;code&gt;docker-compose.yaml&lt;/code&gt; for local development and a Helm chart (or raw manifests) for Kubernetes. They describe the same workload, but diverge constantly. A developer adds an environment variable — it needs to go in three places. You add a new service dependency — it needs to be wired up differently in each environment. The files drift apart. Problems appear in staging that weren&amp;rsquo;t present locally.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tailscale: The WireGuard Mesh VPN That Actually Works Everywhere</title>
      <link>/posts/tailscale-complete-guide/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tailscale-complete-guide/</guid>
      <description>&lt;p&gt;WireGuard is the best VPN protocol ever written. It is also, fundamentally, a plumbing primitive: fast, minimal, and deliberately devoid of any mechanism to find peers, traverse NAT, exchange keys automatically, or handle the coordination that makes a network useful. You still need to copy public keys around, manage IP address assignments, open firewall ports, and configure routes manually.&lt;/p&gt;&#xA;&lt;p&gt;Tailscale is the answer to the question &amp;ldquo;what if WireGuard had an operations layer?&amp;rdquo; It takes WireGuard&amp;rsquo;s cryptography and tunneling, wraps it with a coordination server, an automatic NAT traversal system, a relay network, and a policy engine, and delivers a mesh VPN where every device can reach every other device — no open ports, no static IPs, no manual key exchange, no router configuration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Alloy: The OpenTelemetry Collector from Grafana</title>
      <link>/posts/grafana-alloy-opentelemetry-collector/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grafana-alloy-opentelemetry-collector/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;re running promtail for log shipping, you&amp;rsquo;re on borrowed time. Promtail hit LTS in February 2025 and reaches end-of-life in early 2026. Grafana Agent is already EOL. The replacement for both — and for Grafana Agent Flow — is &lt;strong&gt;Grafana Alloy&lt;/strong&gt;, announced at GrafanaCON 2024.&lt;/p&gt;&#xA;&lt;p&gt;Alloy is Grafana&amp;rsquo;s distribution of the OpenTelemetry Collector, but that description undersells it. It combines native Prometheus scraping with OpenTelemetry&amp;rsquo;s receiver/processor/exporter pipeline model, adds a programmable configuration language, ships a live debugging UI, and supports metrics, logs, traces, and continuous profiles in a single agent. As of 2026, over 525,000 Alloy instances are running in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kavita: Self-Hosted Reading Server for Manga, Comics, and Ebooks</title>
      <link>/posts/kavita-self-hosted-reading-server/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kavita-self-hosted-reading-server/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve ever wanted Jellyfin-style library management for your book and manga collection, Kavita is the closest thing to it. It&amp;rsquo;s a self-hosted reading server that automatically organizes manga, comics, light novels, and ebooks into series, tracks your reading progress across devices, and serves content via a polished web reader or OPDS to third-party apps.&lt;/p&gt;&#xA;&lt;p&gt;With 10,000+ GitHub stars and regular releases, it&amp;rsquo;s the most actively maintained option in the self-hosted comic/manga server space. The core is open-source and fully functional without paying anything — Kavita+ (a paid subscription) adds metadata syncing with AniList and scrobbling, but everything else works out of the box.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Miniflux: Minimal Self-Hosted RSS</title>
      <link>/posts/miniflux-self-hosted-rss/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/miniflux-self-hosted-rss/</guid>
      <description>&lt;p&gt;RSS never died. Millions of people still use it — they just moved to centralized services like Feedly and Inoreader where someone else manages the infrastructure. If you&amp;rsquo;d rather own your reading workflow, Miniflux is the cleanest option in the self-hosted RSS space.&lt;/p&gt;&#xA;&lt;p&gt;Miniflux is a deliberately minimalist feed reader: a single statically-compiled Go binary, a PostgreSQL database, and a server-rendered web UI with no JavaScript bloat. It&amp;rsquo;s fast, it&amp;rsquo;s simple to operate, and it integrates with Fever API clients so you can use a native mobile app if you prefer. Created by Frédéric Guillot and licensed Apache 2.0, it&amp;rsquo;s been actively maintained for years with a clear philosophy: improve what exists rather than pile on features.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stirling PDF: Self-Hosted PDF Swiss Army Knife</title>
      <link>/posts/stirling-pdf/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/stirling-pdf/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve ever pasted a sensitive contract into a cloud PDF tool, you&amp;rsquo;ve probably had a moment of mild dread immediately after clicking &amp;ldquo;Convert.&amp;rdquo; Stirling-PDF fixes that. It&amp;rsquo;s an open-source, self-hosted web application that brings 50+ PDF operations — merge, split, OCR, compress, convert, sign, redact, watermark — under one roof, running entirely within your own infrastructure.&lt;/p&gt;&#xA;&lt;p&gt;With 76,000+ GitHub stars, it&amp;rsquo;s currently the most-starred PDF application on the platform. The project is mature, actively maintained, and ships official Docker images for both &lt;code&gt;amd64&lt;/code&gt; and &lt;code&gt;arm64&lt;/code&gt;. Whether you&amp;rsquo;re running it on a Raspberry Pi or a beefy homelab server, there&amp;rsquo;s an image tier to match.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Teleport: Zero-Trust Access for Infrastructure</title>
      <link>/posts/teleport-zero-trust-infrastructure-access/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/teleport-zero-trust-infrastructure-access/</guid>
      <description>&lt;p&gt;Most infrastructure access is held together with the digital equivalent of sticky notes. SSH keys copied to dozens of servers, nobody sure which ones are still active. Database passwords shared in a Slack thread six months ago. Kubernetes kubeconfigs with long-lived tokens sitting in &lt;code&gt;~/.kube/config&lt;/code&gt; forever. A VPN that grants access to everything once you&amp;rsquo;re inside.&lt;/p&gt;&#xA;&lt;p&gt;Teleport replaces all of it with short-lived certificates, identity-aware proxying, and a complete audit trail. Every connection goes through the Teleport proxy. Every session is logged. Every credential expires in hours, not years. Access is granted based on who you are and what role you hold — not whether your static key happens to be on the server.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wallos: Take Control of Your Subscription Sprawl</title>
      <link>/posts/wallos-subscription-tracker/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wallos-subscription-tracker/</guid>
      <description>&lt;p&gt;Subscription creep is real. Between streaming services, SaaS tools, domain registrations, VPS providers, cloud storage, and a half-dozen other recurring charges, most people have no clear picture of what they&amp;rsquo;re actually spending every month. Commercial apps like Rocket Money and Copilot will track this for you — but they monetize your financial data to do it.&lt;/p&gt;&#xA;&lt;p&gt;Wallos is the self-hosted alternative: a PHP/SQLite web app that tracks your subscriptions locally, alerts you before renewals hit, handles multiple currencies, and never touches an external server unless you ask it to. It has 7,600+ GitHub stars and ships 190+ releases — this is not an abandoned side project.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apache Iceberg: Table Format for the Data Lakehouse</title>
      <link>/posts/apache-iceberg-table-format-data-lakehouse/</link>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apache-iceberg-table-format-data-lakehouse/</guid>
      <description>&lt;p&gt;Storing analytical data in Parquet files on S3 sounds simple. It works until you need to update a row. Or rename a column. Or query what the table looked like last Tuesday. Or have two jobs writing at the same time without corrupting each other. At that point you either bolt on a complex orchestration layer or you discover that your &amp;ldquo;data lake&amp;rdquo; is actually just a pile of files with no guarantees.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Buf: The Modern Protobuf Toolchain</title>
      <link>/posts/buf-modern-protobuf-toolchain/</link>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/buf-modern-protobuf-toolchain/</guid>
      <description>&lt;p&gt;Protobuf is one of the best API description formats available — strongly typed, language-agnostic, compact, and fast. But the tooling around it has always been painful. &lt;code&gt;protoc&lt;/code&gt; requires manually managing a binary, wiring together plugins with obscure flags, installing language runtimes for each plugin, and running fragile shell scripts to generate code. There&amp;rsquo;s no linting, no breaking change detection, no registry for sharing schemas, and no way to know if the change you just made silently broke a consumer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Trivy: Container and IaC Vulnerability Scanning</title>
      <link>/posts/trivy-container-iac-vulnerability-scanning/</link>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/trivy-container-iac-vulnerability-scanning/</guid>
      <description>&lt;p&gt;Every container you ship has a bill of materials: the OS packages, language libraries, and binaries baked into the image. Most of them have vulnerabilities. Your job is to know which ones, triage by severity and fix availability, and not block shipping over a LOW-severity CVE in a library you don&amp;rsquo;t actually call.&lt;/p&gt;&#xA;&lt;p&gt;Trivy makes that practical. It&amp;rsquo;s a single binary that scans container images, filesystems, git repositories, Terraform configs, Kubernetes manifests, running clusters, and generates SBOMs — all without a database server or account signup. Install it, point it at something, get results in seconds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Home Network Monitoring with ntopng and LibreNMS</title>
      <link>/posts/home-network-monitoring-ntopng-librenms/</link>
      <pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-network-monitoring-ntopng-librenms/</guid>
      <description>&lt;p&gt;Most home network problems fall into two categories: something stopped working, or something is eating all your bandwidth. These are fundamentally different questions that require different tools to answer.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;LibreNMS&lt;/strong&gt; answers &amp;ldquo;is it working?&amp;rdquo; — it polls your router, switch, NAS, and servers over SNMP every five minutes and alerts you when an interface goes down, CPU spikes, or disk fills up. It discovers devices automatically, draws topology maps, and stores years of performance graphs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenCost: Kubernetes Cost Attribution</title>
      <link>/posts/opencost-kubernetes-cost-attribution/</link>
      <pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opencost-kubernetes-cost-attribution/</guid>
      <description>&lt;p&gt;Your Kubernetes cluster bill arrives as a single number. The platform team knows the total. Nobody knows which team or workload generated which portion of it. When you ask &amp;ldquo;why did our bill go up 40% this month?&amp;rdquo; nobody has a good answer.&lt;/p&gt;&#xA;&lt;p&gt;OpenCost solves this. It&amp;rsquo;s a CNCF project that runs inside your cluster, watches resource allocation and usage, pulls live pricing from your cloud provider&amp;rsquo;s API, and continuously computes the cost of every pod, deployment, namespace, and label. The result is a per-namespace cost breakdown that lets you answer &amp;ldquo;the data-pipeline namespace now costs $3,200/month because someone deployed a Spark job with a 128Gi memory request.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>API Rate Limiting Patterns: Algorithms, Redis Implementations, and Client Communication</title>
      <link>/posts/api-rate-limiting-patterns/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/api-rate-limiting-patterns/</guid>
      <description>&lt;p&gt;Rate limiting is one of those things that seems simple until you actually implement it. &amp;ldquo;Allow 100 requests per minute&amp;rdquo; sounds trivial. Then you discover that naive implementations let users burst 200 requests by straddling a minute boundary, that distributed systems require atomic operations across nodes, that different endpoints need different limits, that you need to tell clients what their limit is and when it resets, and that the wrong algorithm can make your service unusable under bursty but legitimate traffic.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Argo CD and GitOps in Production: App of Apps, Rollouts, and Multi-Cluster Management</title>
      <link>/posts/argocd-gitops-in-production/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/argocd-gitops-in-production/</guid>
      <description>&lt;p&gt;GitOps is a simple idea with deep implications: the desired state of your infrastructure lives in Git, and an automated system continuously reconciles the actual state toward it. You never &lt;code&gt;kubectl apply&lt;/code&gt; in production. You never SSH into a server to patch a config. Every change is a pull request, every deployment is a merge, and the entire history of what changed and why lives in your version control system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Authentik: A Self-Hosted Identity Provider for Everything</title>
      <link>/posts/authentik-self-hosted-identity-provider/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/authentik-self-hosted-identity-provider/</guid>
      <description>&lt;p&gt;Every self-hosted stack eventually grows to the point where managing separate logins for Grafana, Gitea, Nextcloud, Proxmox, Portainer, Jellyfin, and a dozen other services becomes painful. Password reuse, no MFA enforcement, and no central audit log of who logged in to what. The obvious fix is Single Sign-On — one login, one MFA prompt, everything else flows through.&lt;/p&gt;&#xA;&lt;p&gt;The enterprise answer is Okta or Azure AD. The self-hosted answer is &lt;a href=&#34;https://goauthentik.io/&#34;&gt;Authentik&lt;/a&gt;: a full-featured identity provider that speaks OIDC, OAuth2, SAML, LDAP, SCIM, and RADIUS. It&amp;rsquo;s mature (used in production at thousands of organizations), actively developed, and runs comfortably on the same homelab hardware as the rest of your stack.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building Internal Data Platforms: The Modern Data Stack in Practice</title>
      <link>/posts/building-internal-data-platforms/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/building-internal-data-platforms/</guid>
      <description>&lt;p&gt;Most companies accumulate data infrastructure organically: a warehouse here, some ad hoc pipelines there, a BI tool bolted on top, and a spreadsheet somewhere that nobody trusts but everyone uses. The result is data chaos — analysts spend 80% of their time wrangling data and 20% actually analyzing it. An internal data platform flips that ratio by standardizing how data moves, transforms, and gets consumed across the organization.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers building a production-grade internal data platform using the modern data stack: a cloud data warehouse, dbt for transformations, Airflow for orchestration, and the practices — data contracts, quality checks, documentation — that make it actually reliable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Capacity Planning for Engineers: Forecasting Growth, Load Testing, and Avoiding Surprise Scaling Events</title>
      <link>/posts/capacity-planning-for-engineers/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/capacity-planning-for-engineers/</guid>
      <description>&lt;h1 id=&#34;capacity-planning-for-engineers-forecasting-growth-load-testing-and-avoiding-surprise-scaling-events&#34;&gt;Capacity Planning for Engineers: Forecasting Growth, Load Testing, and Avoiding Surprise Scaling Events&lt;/h1&gt;&#xA;&lt;p&gt;Few things feel worse operationally than a service falling over because traffic doubled during a product launch you knew was coming for weeks. Capacity planning is the discipline that turns &amp;ldquo;I hope we have enough&amp;rdquo; into &amp;ldquo;I know we have enough — and here&amp;rsquo;s the data.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s also deeply undervalued. Most teams treat capacity as an afterthought until a scaling event causes an incident. Then they over-provision reactively, spend too much money, and repeat the cycle when the next surprise comes. Systematic capacity planning breaks this cycle: you measure your system&amp;rsquo;s limits, model your expected growth, provision with explicit headroom, and validate your assumptions with load tests before real traffic arrives.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Change Data Capture with Debezium: Streaming Database Changes in Real Time</title>
      <link>/posts/change-data-capture-debezium/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/change-data-capture-debezium/</guid>
      <description>&lt;h1 id=&#34;change-data-capture-with-debezium-streaming-database-changes-in-real-time&#34;&gt;Change Data Capture with Debezium: Streaming Database Changes in Real Time&lt;/h1&gt;&#xA;&lt;p&gt;Every production database is a stream of changes disguised as a table. Every INSERT, UPDATE, and DELETE is an event — but conventional applications discard that event the moment the transaction commits, leaving only the final state. Change Data Capture (CDC) recovers that stream and makes it available to the rest of your system in real time.&lt;/p&gt;&#xA;&lt;p&gt;Debezium is the leading open-source CDC platform. It taps into database transaction logs — PostgreSQL&amp;rsquo;s WAL, MySQL&amp;rsquo;s binlog, MongoDB&amp;rsquo;s oplog — and publishes every change as a structured event to Kafka. Downstream systems subscribe to these events and react: search indexes stay current, caches invalidate automatically, data warehouses receive row-level changes without polling, and microservices react to domain events without tight coupling.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chaos Engineering in Practice: Breaking Things on Purpose to Build Unbreakable Systems</title>
      <link>/posts/chaos-engineering-in-practice/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/chaos-engineering-in-practice/</guid>
      <description>&lt;h1 id=&#34;chaos-engineering-in-practice-breaking-things-on-purpose-to-build-unbreakable-systems&#34;&gt;Chaos Engineering in Practice: Breaking Things on Purpose to Build Unbreakable Systems&lt;/h1&gt;&#xA;&lt;p&gt;In 2011, Netflix engineers had a problem: they were moving to AWS and needed confidence that their system would survive infrastructure failures. They couldn&amp;rsquo;t just hope it would work — they needed to &lt;em&gt;prove&lt;/em&gt; it. So they built Chaos Monkey, a tool that randomly terminated EC2 instances in production during business hours. If a random instance could die at any moment, engineers were forced to build systems that could handle it gracefully.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chaos Engineering on a Budget: Building Resilience Without Breaking the Bank</title>
      <link>/posts/chaos-engineering-on-a-budget/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/chaos-engineering-on-a-budget/</guid>
      <description>&lt;p&gt;The 2011 AWS us-east-1 outage took down Reddit, Foursquare, Quora, and dozens of other major services. Netflix stayed up. The difference wasn&amp;rsquo;t better hardware or more engineers — it was Chaos Monkey, Netflix&amp;rsquo;s tool for randomly terminating production instances. By forcing themselves to survive failures constantly, Netflix had built infrastructure that could absorb the real thing.&lt;/p&gt;&#xA;&lt;p&gt;Most teams know chaos engineering exists. Few practice it, usually citing cost, risk, or complexity. This guide is about removing all three excuses: how to run meaningful chaos experiments on a homelab, a small team&amp;rsquo;s staging environment, or even production, without a chaos engineering team or an enterprise budget.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ClickHouse for Observability: Logs, Metrics, and Traces at Scale</title>
      <link>/posts/clickhouse-for-observability/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/clickhouse-for-observability/</guid>
      <description>&lt;p&gt;Observability data is some of the highest-volume data a production system generates. A modest microservices platform might produce millions of log lines per minute, thousands of metric data points per second, and hundreds of distributed traces per request. Most teams eventually hit the wall with Elasticsearch: high memory requirements, expensive storage, slow aggregations, and a query language that punishes complex analytics.&lt;/p&gt;&#xA;&lt;p&gt;ClickHouse is a columnar OLAP database that changes the economics entirely. It ingests billions of rows per second, compresses data 10-50x better than row-oriented stores, and executes analytical queries that would take minutes in Elasticsearch in milliseconds. Grafana, Signoz, Highlight.io, and Cloudflare all run ClickHouse as their observability backbone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dagger: Portable CI/CD Pipelines That Run Everywhere</title>
      <link>/posts/dagger-portable-cicd-pipelines/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dagger-portable-cicd-pipelines/</guid>
      <description>&lt;p&gt;Every CI/CD pipeline eventually develops the same set of problems. Debugging requires pushing commits and waiting for remote runners. Secrets behave differently locally. The YAML grows to 600 lines with nested conditionals and custom actions nobody understands. A new engineer spends their first week figuring out why the pipeline works in staging but not production.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://dagger.io/&#34;&gt;Dagger&lt;/a&gt; attacks this at the root: your pipeline is code — real code, in Go, Python, or TypeScript — that runs inside containers on your laptop. The exact same code runs in GitHub Actions, GitLab CI, CircleCI, Jenkins, or Buildkite. No YAML. No CI vendor lock-in. No &amp;ldquo;push a commit to test a pipeline change.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>dbt Core in Practice: Data Modeling That Doesn&#39;t Rot</title>
      <link>/posts/dbt-core-in-practice/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dbt-core-in-practice/</guid>
      <description>&lt;p&gt;SQL analytics code has a reputation for rotting. A clever CTE someone wrote in 2021 now powers three dashboards, nobody knows how it works, it references tables that were renamed, and the column &lt;code&gt;revenue_adj&lt;/code&gt; means something different depending on who you ask. Half the team has their own version of the same transformation living in a Jupyter notebook.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.getdbt.com/&#34;&gt;dbt&lt;/a&gt; (data build tool) is the answer the data engineering community converged on: treat your SQL transformations the way software engineers treat application code. Version control. Tests. Documentation. Modular, reusable models. Dependency graphs. Automated runs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Designing for Observability: Building Applications You Can Actually Debug</title>
      <link>/posts/designing-for-observability/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/designing-for-observability/</guid>
      <description>&lt;p&gt;Observability is not a monitoring stack you bolt on after launch. It is a property of the application itself — baked into how it logs, what it measures, how it surfaces health, and how it behaves when its dependencies fail. A system that is observable lets you ask new questions about its behavior in production using the data it already emits, without deploying new code. A system that is not observable forces you to guess.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DesignSync for Git Users: A Complete Guide to EDA Version Control</title>
      <link>/posts/designsync-for-git-users/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/designsync-for-git-users/</guid>
      <description>&lt;p&gt;If you are joining a semiconductor or mixed-signal hardware team from a software background, one of the first surprises is version control. Instead of Git, you are likely staring at &lt;code&gt;dssc&lt;/code&gt;, &lt;code&gt;sync://&lt;/code&gt; URLs, vaults, locked checkouts, and manifests. The concepts exist in Git too — they just go by different names and carry different assumptions.&lt;/p&gt;&#xA;&lt;p&gt;This guide maps everything you know from Git onto DesignSync (ENOVIA Synchronicity DesignSync Data Manager, from Dassault Systèmes/Siemens EDA). It assumes you are already comfortable with Git and need to get productive in DesignSync without wading through a 400-page manual.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DNS over HTTPS and DNS over TLS: Encrypting the Internet&#39;s Phone Book</title>
      <link>/posts/dns-over-https-dns-over-tls/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dns-over-https-dns-over-tls/</guid>
      <description>&lt;p&gt;Every website you visit starts with a DNS lookup. Your browser asks a resolver &amp;ldquo;what&amp;rsquo;s the IP address for github.com?&amp;rdquo; and gets an answer. For most of the internet&amp;rsquo;s history, this exchange happened in plaintext over UDP — visible to your ISP, your network provider, anyone on the path between you and the resolver.&lt;/p&gt;&#xA;&lt;p&gt;DNS over HTTPS (DoH) and DNS over TLS (DoT) fix this. Both protocols encrypt DNS queries, preventing eavesdropping and tampering. They differ in &lt;em&gt;how&lt;/em&gt; they do it, which has implications for deployment, privacy, and control.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DuckDB for Analytics Engineers: In-Process OLAP That Replaces Your Spark Cluster</title>
      <link>/posts/duckdb-for-analytics-engineers/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/duckdb-for-analytics-engineers/</guid>
      <description>&lt;h1 id=&#34;duckdb-for-analytics-engineers-in-process-olap-that-replaces-your-spark-cluster&#34;&gt;DuckDB for Analytics Engineers: In-Process OLAP That Replaces Your Spark Cluster&lt;/h1&gt;&#xA;&lt;p&gt;For years, the analytics engineering stack had a gap in the middle. SQLite was fast and embeddable but row-oriented and useless for aggregations. Postgres was great for OLTP but slow for analytical queries on large datasets. If you needed real analytical performance, you spun up Spark, stood up Redshift or BigQuery, or deployed ClickHouse — all of which require significant operational overhead for what might be a single-engineer data team running batch jobs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fuzzing for Developers: Finding Bugs Machines Can&#39;t Ignore</title>
      <link>/posts/fuzzing-for-developers/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fuzzing-for-developers/</guid>
      <description>&lt;h1 id=&#34;fuzzing-for-developers-finding-bugs-machines-cant-ignore&#34;&gt;Fuzzing for Developers: Finding Bugs Machines Can&amp;rsquo;t Ignore&lt;/h1&gt;&#xA;&lt;p&gt;Fuzzing is one of the most effective techniques for finding security vulnerabilities and correctness bugs — and one of the most underused by application developers. The security community has known this for decades: Google&amp;rsquo;s OSS-Fuzz program has found over 10,000 vulnerabilities in open source projects since 2016. Heartbleed, Shellshock, and countless critical CVEs in media parsers, network protocols, and compression libraries were all found or could have been found by fuzzing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Gateway API: The Future of Kubernetes Ingress</title>
      <link>/posts/kubernetes-gateway-api/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-gateway-api/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve worked with Kubernetes Ingress resources for any length of time, you&amp;rsquo;ve hit the walls. You want to split traffic between two backend versions — no standard way to do it. You want to route based on a request header — vendor annotation required. You want your platform team to control which TLS certificates are allowed while letting application teams manage their own routes — impossible without hacking the RBAC model. You end up with dozens of &lt;code&gt;nginx.ingress.kubernetes.io/&lt;/code&gt; annotations that tie you to a specific implementation and break the moment you switch controllers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HAProxy Deep Dive: Load Balancing, Health Checks, ACLs, and Production Tuning</title>
      <link>/posts/haproxy-deep-dive/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/haproxy-deep-dive/</guid>
      <description>&lt;p&gt;HAProxy has been the gold standard for software load balancing and proxying for over two decades. It powers high-traffic sites at GitHub, Reddit, Stack Overflow, and Airbnb. While cloud-native alternatives like Envoy and Nginx proliferate, HAProxy maintains a unique position: a single-purpose tool that does load balancing and proxying better than almost anything else, with a configuration language expressive enough to handle nearly any routing requirement, and performance characteristics that remain exceptional even at millions of requests per second.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Immich Deep Dive: AI-Powered Photo Management for Your Homelab</title>
      <link>/posts/immich-deep-dive/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/immich-deep-dive/</guid>
      <description>&lt;p&gt;Your phone has 30,000 photos. Google Photos holds them hostage behind an ever-shrinking free tier. Apple iCloud costs $2.99/month and makes sharing difficult. You want your memories on hardware you own, with search that actually works, face recognition that groups your family together automatically, and mobile backup that just runs.&lt;/p&gt;&#xA;&lt;p&gt;Immich is that solution. It&amp;rsquo;s the self-hosted photo management app that has done for photos what Jellyfin did for video — built a genuinely good, open-source alternative to the cloud giants. With AI-powered semantic search, DBSCAN-based face clustering, hardware-accelerated ML, and a polished mobile app, Immich is no longer a compromise. For many people it&amp;rsquo;s better than Google Photos.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Immich: Self-Hosted Google Photos That Actually Competes</title>
      <link>/posts/immich-self-hosted-google-photos/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/immich-self-hosted-google-photos/</guid>
      <description>&lt;p&gt;For years, self-hosted photo management was a compromise. You gave up Google Photos&amp;rsquo; face recognition, automatic albums, and instant mobile backup in exchange for owning your data. Immich has largely closed that gap. It does face recognition, object detection, automatic memory albums, map view, shared albums, partner sharing, a polished mobile app with background sync, and it runs on commodity hardware.&lt;/p&gt;&#xA;&lt;p&gt;If you have a homelab and still have your photos in Google Photos or iCloud, this guide will walk you through migrating to a setup that you fully control, that performs well at scale, and that keeps getting better.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Internal Developer Platforms with Backstage: Building the Golden Path</title>
      <link>/posts/internal-developer-platforms-with-backstage/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/internal-developer-platforms-with-backstage/</guid>
      <description>&lt;p&gt;Every engineering organization above a certain size hits the same wall: too many services, too many tools, and tribal knowledge scattered across Slack threads, outdated wikis, and the heads of the three engineers who were there at the beginning. Onboarding takes weeks. Finding who owns a service requires asking around. Running a new microservice means copying an old one and hoping you got all the Dockerfile, CI pipeline, Helm chart, and monitoring configuration right.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Jellyfin vs Plex vs Emby: The Self-Hosted Media Server Showdown</title>
      <link>/posts/jellyfin-vs-plex-vs-emby/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/jellyfin-vs-plex-vs-emby/</guid>
      <description>&lt;p&gt;At some point every homelab operator accumulates a media library — ripped Blu-rays, downloaded films, a decade of TV shows — and needs a way to actually watch it. Three projects dominate self-hosted media serving: &lt;strong&gt;Plex&lt;/strong&gt;, the polished incumbent with a freemium model; &lt;strong&gt;Jellyfin&lt;/strong&gt;, the fully open-source fork that costs nothing; and &lt;strong&gt;Emby&lt;/strong&gt;, the middle ground that went commercial and split the community.&lt;/p&gt;&#xA;&lt;p&gt;The right choice depends on your priorities. This guide covers each platform honestly: architecture, hardware transcoding setup (where most people get stuck), client support, metadata management, and the real cost of each option — so you can pick once and not regret it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Karpenter: Intelligent Node Autoscaling for Kubernetes</title>
      <link>/posts/karpenter-intelligent-node-autoscaling/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/karpenter-intelligent-node-autoscaling/</guid>
      <description>&lt;p&gt;The Kubernetes Cluster Autoscaler has served clusters well for years, but it was designed around a fundamental constraint: it scales pre-defined Auto Scaling Groups (ASGs). When pods are pending, it picks an ASG, scales it up, waits for the node to join, and eventually the pod gets scheduled. This works, but it&amp;rsquo;s slow (2–10 minutes to get a node), inflexible (you&amp;rsquo;re locked into the instance types in each ASG), and wasteful (nodes are often over-provisioned to catch the next burst).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mise: The Universal Version Manager That Replaces Everything</title>
      <link>/posts/mise-universal-version-manager/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mise-universal-version-manager/</guid>
      <description>&lt;p&gt;Most developers carry a silent tax: the cognitive overhead of juggling version managers. &lt;code&gt;nvm&lt;/code&gt; for Node, &lt;code&gt;pyenv&lt;/code&gt; for Python, &lt;code&gt;rbenv&lt;/code&gt; or &lt;code&gt;asdf&lt;/code&gt; for Ruby, &lt;code&gt;sdkman&lt;/code&gt; for Java/Kotlin, &lt;code&gt;tfenv&lt;/code&gt; for Terraform, &lt;code&gt;goenv&lt;/code&gt; for Go. Each has its own install process, its own shell integration, its own config file format, and its own quirks. Switching between projects means remembering which version manager controls which runtime, why your shell feels slow, and why &lt;code&gt;node --version&lt;/code&gt; returns something unexpected.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Monitoring Your Homelab with Prometheus and Grafana: The Complete Stack</title>
      <link>/posts/homelab-monitoring-prometheus-grafana/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/homelab-monitoring-prometheus-grafana/</guid>
      <description>&lt;p&gt;Most homelabs start with good intentions about monitoring. You install a service, it runs, you move on. Months later a disk fills up silently, a container crashes and restarts in a loop all weekend, or your NAS has been running at 95°C for two weeks and you only find out when it dies.&lt;/p&gt;&#xA;&lt;p&gt;A proper monitoring stack prevents all of this. Prometheus scrapes metrics from your services every 15 seconds, stores them in a time-series database, and fires alerts when anything crosses a threshold. Grafana visualizes everything in dashboards you can actually read at a glance. The whole stack runs in Docker Compose and uses less than 1GB RAM on a Raspberry Pi 4.&lt;/p&gt;</description>
    </item>
    <item>
      <title>mTLS Everything: Certificate-Based Service Identity with SPIFFE, SPIRE, and Envoy</title>
      <link>/posts/mtls-everything/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mtls-everything/</guid>
      <description>&lt;h1 id=&#34;mtls-everything-certificate-based-service-identity-with-spiffe-spire-and-envoy&#34;&gt;mTLS Everything: Certificate-Based Service Identity with SPIFFE, SPIRE, and Envoy&lt;/h1&gt;&#xA;&lt;p&gt;Standard TLS authenticates the &lt;em&gt;server&lt;/em&gt; to the &lt;em&gt;client&lt;/em&gt;. Your browser verifies that &lt;code&gt;api.example.com&lt;/code&gt; holds a valid certificate for that domain before trusting it. But in a microservices environment, you also want the server to verify the &lt;em&gt;client&lt;/em&gt; — to confirm that the service calling your payment API is actually your order service, not a compromised pod that somehow got network access.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nextcloud: Your Own Google Drive (That You Actually Control)</title>
      <link>/posts/nextcloud-self-hosted-google-drive/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nextcloud-self-hosted-google-drive/</guid>
      <description>&lt;p&gt;Google Drive, iCloud, and Dropbox are convenient until they aren&amp;rsquo;t — a price hike, a privacy concern, a terms-of-service change, or simply the realization that your family photos and financial documents live on someone else&amp;rsquo;s server. Nextcloud is the self-hosted alternative: a full-featured file sync and collaboration platform that runs on your hardware, under your control.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the full deployment lifecycle: Docker Compose with PostgreSQL and Redis, performance tuning that keeps Nextcloud responsive even with thousands of files, external storage backends for NAS integration, Nextcloud Office for in-browser document editing, mobile sync configuration, and the maintenance tasks that keep everything running smoothly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenTelemetry: One Instrumentation to Rule Them All</title>
      <link>/posts/opentelemetry-instrumentation/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opentelemetry-instrumentation/</guid>
      <description>&lt;p&gt;Before OpenTelemetry, instrumenting a service meant picking a vendor — Datadog, New Relic, Honeycomb, Jaeger — and writing code that was coupled to that vendor&amp;rsquo;s SDK. Switching backends meant rewriting instrumentation. Running multiple backends meant running multiple agents. The observability space was a collection of proprietary silos.&lt;/p&gt;&#xA;&lt;p&gt;OpenTelemetry (OTel) is the CNCF project that standardizes how telemetry data — traces, metrics, and logs — is collected, processed, and exported. You instrument once against the OTel API, and the backend is a configuration decision, not a code decision. The same instrumented service can send traces to Jaeger today, Tempo tomorrow, and Honeycomb next month without touching a line of application code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paperless-ngx: Building a Document Management System That Actually Works</title>
      <link>/posts/paperless-ngx-going-paperless/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/paperless-ngx-going-paperless/</guid>
      <description>&lt;p&gt;Paper has a way of piling up — utility bills, insurance documents, tax records, medical forms. Scanning them into a folder structure solves the physical problem but not the organizational one: you still end up with &lt;code&gt;scan_2024_03_final_REAL.pdf&lt;/code&gt; in a directory tree you half-remember.&lt;/p&gt;&#xA;&lt;p&gt;Paperless-ngx solves this. It&amp;rsquo;s a document management system that ingests PDFs and images, runs OCR to make them full-text searchable, and lets you tag, classify, and find anything instantly. This guide covers deploying it in Docker Compose, building an automated scanning pipeline, and configuring the features that make it genuinely useful.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pi-hole and AdGuard Home: Network-Wide Ad Blocking for Your Homelab</title>
      <link>/posts/pihole-adguard-home/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pihole-adguard-home/</guid>
      <description>&lt;p&gt;Every device on your network — phones, laptops, smart TVs, IoT sensors — makes DNS queries before loading ads, tracking pixels, and telemetry endpoints. A DNS-level ad blocker sits between those devices and the internet and answers those queries with &amp;ldquo;that domain doesn&amp;rsquo;t exist,&amp;rdquo; silently dropping ads and trackers before they ever reach the device. No browser extensions needed, no per-device configuration, no ads in apps or smart TVs.&lt;/p&gt;&#xA;&lt;p&gt;Pi-hole and AdGuard Home are the two leading self-hosted DNS sinkholes. Both work beautifully; they have different strengths. This guide covers both, with enough depth to run either in production on your home network.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL Performance Tuning: From Slow Queries to a Database That Purrs</title>
      <link>/posts/postgresql-performance-tuning/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/postgresql-performance-tuning/</guid>
      <description>&lt;p&gt;PostgreSQL works well out of the box until it doesn&amp;rsquo;t. A query that took 10ms starts taking 4 seconds. Table scans creep into your query plans. Autovacuum locks appear in your logs. Connections pile up and new ones start refusing. These aren&amp;rsquo;t mysterious — PostgreSQL gives you excellent observability into exactly what&amp;rsquo;s happening, if you know where to look.&lt;/p&gt;&#xA;&lt;p&gt;This guide is organized around the actual workflow for diagnosing and fixing performance problems: find the slow queries, understand why they&amp;rsquo;re slow, fix them at the query or schema level, tune the server configuration, and prevent connection exhaustion. Each section goes deep enough to handle real production situations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Production Readiness Reviews: A Framework for Shipping Services That Don&#39;t Break</title>
      <link>/posts/production-readiness-reviews/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/production-readiness-reviews/</guid>
      <description>&lt;h1 id=&#34;production-readiness-reviews-a-framework-for-shipping-services-that-dont-break&#34;&gt;Production Readiness Reviews: A Framework for Shipping Services That Don&amp;rsquo;t Break&lt;/h1&gt;&#xA;&lt;p&gt;Every engineering team has shipped something that wasn&amp;rsquo;t ready. Not because the code was bad, but because it lacked the operational infrastructure around it: no meaningful alerts, no runbooks anyone could follow at 3 AM, no defined SLOs, no load test against realistic traffic. The service worked in staging. Then production found the gaps.&lt;/p&gt;&#xA;&lt;p&gt;A Production Readiness Review (PRR) is a structured conversation that happens &lt;em&gt;before&lt;/em&gt; a service goes live — or before a major new feature launches on an existing service. It asks a systematic set of questions: Can we observe what this service is doing? Can we respond when it breaks? Does it degrade gracefully? Are there runbooks? Does it meet its SLOs under load?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Progressive Delivery: Safe Deployments with Feature Flags, Canaries, and Argo Rollouts</title>
      <link>/posts/progressive-delivery/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/progressive-delivery/</guid>
      <description>&lt;h1 id=&#34;progressive-delivery-safe-deployments-with-feature-flags-canaries-and-argo-rollouts&#34;&gt;Progressive Delivery: Safe Deployments with Feature Flags, Canaries, and Argo Rollouts&lt;/h1&gt;&#xA;&lt;p&gt;Traditional deployments are binary: the old version is running, then the new version is running. Every deployment is a calculated gamble — you tested in staging, you reviewed the code, but you won&amp;rsquo;t really know if it works until it&amp;rsquo;s in production handling real traffic. If it fails, you&amp;rsquo;re scrambling to roll back while users experience errors.&lt;/p&gt;&#xA;&lt;p&gt;Progressive delivery is the set of techniques that makes deployments incremental rather than binary. Instead of &amp;ldquo;old code off, new code on,&amp;rdquo; you ask: &amp;ldquo;What&amp;rsquo;s the smallest amount of traffic we can send to the new version to learn whether it&amp;rsquo;s safe, before we commit?&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Real-Time Streaming with Apache Flink: Stateful Stream Processing at Scale</title>
      <link>/posts/real-time-streaming-apache-flink/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/real-time-streaming-apache-flink/</guid>
      <description>&lt;p&gt;Apache Flink is the most capable open-source stream processing framework available. While Kafka handles data transport and Spark handles batch analytics, Flink sits in the middle doing what neither does well: stateful, low-latency, exactly-once stream processing at arbitrary scale.&lt;/p&gt;&#xA;&lt;p&gt;This guide goes from first principles to production-grade Flink jobs deployed on Kubernetes, covering the concepts you need to understand to build reliable real-time pipelines.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;why-flink-not-spark-streaming-or-kafka-streams&#34;&gt;Why Flink, Not Spark Streaming or Kafka Streams?&lt;/h2&gt;&#xA;&lt;p&gt;The streaming landscape is crowded. Here&amp;rsquo;s where Flink fits:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis Beyond Caching: Streams, Pub/Sub, Search, and When Redis Is Your Primary Database</title>
      <link>/posts/redis-beyond-caching/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/redis-beyond-caching/</guid>
      <description>&lt;p&gt;Most engineers encounter Redis as a cache: store a serialized object, set a TTL, move on. That&amp;rsquo;s a fine use of Redis, but it&amp;rsquo;s the equivalent of buying a Swiss Army knife and only using the blade. Redis is a data structure server — not just a key-value store — with native support for lists, sorted sets, streams, pub/sub, geospatial indexes, probabilistic data structures, and with modules, full-text search and JSON documents.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Renovate Bot Deep Dive: Automated Dependency Updates That Don&#39;t Drive You Crazy</title>
      <link>/posts/renovate-bot-deep-dive/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/renovate-bot-deep-dive/</guid>
      <description>&lt;p&gt;Dependency management is one of those tasks that&amp;rsquo;s easy to ignore until it becomes critical. Dependencies drift behind. A CVE drops. You discover your Node app is four major versions behind Express, your Dockerfile pulls &lt;code&gt;node:14&lt;/code&gt; which reached EOL two years ago, and your Terraform providers haven&amp;rsquo;t been updated since the initial commit.&lt;/p&gt;&#xA;&lt;p&gt;Renovate Bot solves this systematically. It scans your repositories for dependencies across every package manager it knows about, opens PRs with precise, atomic updates, and optionally merges them automatically based on rules you define. Unlike Dependabot, which is tightly coupled to GitHub and limited in configurability, Renovate runs anywhere, understands more package managers, and has configuration deep enough to handle the most opinionated workflows.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Runtime Security with Falco: Syscall-Level Threat Detection for Kubernetes</title>
      <link>/posts/runtime-security-with-falco/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/runtime-security-with-falco/</guid>
      <description>&lt;h1 id=&#34;runtime-security-with-falco-syscall-level-threat-detection-for-kubernetes&#34;&gt;Runtime Security with Falco: Syscall-Level Threat Detection for Kubernetes&lt;/h1&gt;&#xA;&lt;p&gt;Container security tools like image scanners (Trivy, Grype) and admission controllers (OPA Gatekeeper, Kyverno) are essential — but they only defend against known bad configurations at deploy time. They can&amp;rsquo;t tell you what&amp;rsquo;s happening &lt;em&gt;right now&lt;/em&gt; inside a running container.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s the gap Falco fills. It sits at the Linux kernel level, watching every system call made by every process on the host. When a container that should only be serving HTTP requests suddenly calls &lt;code&gt;execve&lt;/code&gt; to spawn a shell, or opens &lt;code&gt;/etc/passwd&lt;/code&gt; for writing, or establishes a network connection to an unexpected IP — Falco sees it in microseconds and fires an alert.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secrets Rotation Without Downtime: Rotating Credentials in Live Systems</title>
      <link>/posts/secrets-rotation-without-downtime/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/secrets-rotation-without-downtime/</guid>
      <description>&lt;p&gt;Rotating secrets in production is one of those problems that sounds simple until you do it. Stop the app, change the password, restart the app — fine for a hobby project. In production, &amp;ldquo;restart the app&amp;rdquo; means downtime, dropped requests, and a deployment pipeline that may take 20 minutes. Multiply that by every database, every API integration, every TLS certificate, on a regular rotation schedule, and you have a maintenance burden that most teams quietly skip.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secure Software Development Lifecycle: Building Security Into Every Phase</title>
      <link>/posts/secure-software-development-lifecycle/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/secure-software-development-lifecycle/</guid>
      <description>&lt;p&gt;Security tacked on at the end of a release cycle is security theater. A vulnerability found in production costs 30x more to fix than the same issue caught at design time — and that&amp;rsquo;s before accounting for breach costs, regulatory penalties, and reputational damage. The Secure Software Development Lifecycle (Secure SDLC or SSDLC) shifts security left: embedding threat modeling, automated scanning, and security gates at every stage so that findings arrive when they&amp;rsquo;re cheapest to fix.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Self-Hosted GitHub Actions Runners: Ephemeral, Scalable, and Cost-Effective CI</title>
      <link>/posts/self-hosted-github-actions-runners/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/self-hosted-github-actions-runners/</guid>
      <description>&lt;p&gt;GitHub-hosted runners are remarkably convenient — push a commit and a fresh Ubuntu VM spins up, runs your workflow, and disappears. But at scale, that convenience gets expensive fast. The 2,000 free minutes per month on the free plan, or even the generous allowances on Team/Enterprise plans, evaporate quickly when your team ships frequently or your builds take more than a few minutes.&lt;/p&gt;&#xA;&lt;p&gt;Self-hosted runners put that compute on your own infrastructure. Done naively — a persistent VM with the runner agent installed — they work but come with problems: stale environments, credential leakage between jobs, a single point of failure. Done properly with ephemeral Kubernetes runners via Actions Runner Controller, you get isolation, autoscaling, and significant cost savings.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Taskfile: A Better Makefile for Modern Development</title>
      <link>/posts/taskfile-a-better-makefile/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/taskfile-a-better-makefile/</guid>
      <description>&lt;p&gt;Every project needs a task runner. Build the binary, run tests, lint code, spin up containers, deploy to staging — these operations need names, documentation, and repeatability. For decades, &lt;code&gt;make&lt;/code&gt; dominated this space. But Makefiles were designed for C compilation in 1976, and the workarounds for using them as a general task runner have accumulated into a fragile mess of &lt;code&gt;.PHONY&lt;/code&gt; declarations, tab indentation traps, and portability nightmares.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://taskfile.dev/&#34;&gt;Taskfile&lt;/a&gt; (the &lt;code&gt;task&lt;/code&gt; command) is a modern task runner built in Go that solves all of this elegantly. It&amp;rsquo;s declarative, readable, cross-platform, and designed from day one for developer experience rather than build artifacts.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The On-Call Handbook: Rotations, Runbooks, and Recovering Without Burning Out</title>
      <link>/posts/on-call-handbook/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/on-call-handbook/</guid>
      <description>&lt;h1 id=&#34;the-on-call-handbook-rotations-runbooks-and-recovering-without-burning-out&#34;&gt;The On-Call Handbook: Rotations, Runbooks, and Recovering Without Burning Out&lt;/h1&gt;&#xA;&lt;p&gt;Being on call is one of the most demanding parts of engineering work. A 3 AM page that wakes you from deep sleep, a cascading failure you&amp;rsquo;ve never seen before, the pressure to fix it fast before users notice — it demands technical skill, clear thinking under stress, and emotional resilience simultaneously.&lt;/p&gt;&#xA;&lt;p&gt;Done badly, on-call destroys engineers. Teams with poorly designed rotations, alert storms, and no runbooks see burnout, attrition, and a perverse incentive structure where the engineers who understand the system least are the ones who suffer most when it breaks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vaultwarden: Running Your Own Password Manager</title>
      <link>/posts/vaultwarden-self-hosted-password-manager/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vaultwarden-self-hosted-password-manager/</guid>
      <description>&lt;p&gt;Every security professional says the same thing: use a password manager. The argument for &lt;em&gt;self-hosting&lt;/em&gt; your password manager is less universally agreed upon, but it&amp;rsquo;s compelling — your vault lives on your hardware, your credentials never touch a third-party server, and you control the backup and recovery process entirely.&lt;/p&gt;&#xA;&lt;p&gt;Vaultwarden (formerly Bitwarden_RS) is an unofficial, lightweight Bitwarden-compatible server written in Rust. It implements the full Bitwarden API, meaning every Bitwarden client — browser extensions, desktop apps, the mobile apps — works with it out of the box. The official Bitwarden server requires 2GB+ of RAM and a SQL Server instance; Vaultwarden runs in under 100MB of RAM on a Raspberry Pi.&lt;/p&gt;</description>
    </item>
    <item>
      <title>VictoriaMetrics: Prometheus at Scale</title>
      <link>/posts/victoriametrics-prometheus-at-scale/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/victoriametrics-prometheus-at-scale/</guid>
      <description>&lt;p&gt;Prometheus is excellent for getting metrics into a Kubernetes cluster quickly. It falls short when you need to store more than a few weeks of data, when you&amp;rsquo;re federating metrics from dozens of clusters, or when your cardinality grows to tens of millions of active time series. The memory consumption alone becomes a scaling problem — Prometheus keeps its entire index in RAM.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://victoriametrics.com/&#34;&gt;VictoriaMetrics&lt;/a&gt; solves exactly these problems. It&amp;rsquo;s a high-performance time-series database that accepts Prometheus &lt;code&gt;remote_write&lt;/code&gt;, speaks PromQL natively, stores data 5–10x more efficiently, and scales horizontally with a clean clustering model. Grafana Cloud, Cloudflare, and dozens of large-scale monitoring deployments run VictoriaMetrics as their metrics backbone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing a CLI Tool in Go: From Zero to Distributable Binary</title>
      <link>/posts/writing-a-cli-tool-in-go/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/writing-a-cli-tool-in-go/</guid>
      <description>&lt;p&gt;Go produces statically compiled binaries that start in milliseconds, ship without runtime dependencies, and cross-compile for any platform from a single machine. These properties make it the language of choice for CLI tooling — it&amp;rsquo;s why Docker, kubectl, Terraform, Hugo, and hundreds of other tools are written in it.&lt;/p&gt;&#xA;&lt;p&gt;This guide builds a realistic CLI tool from scratch: &lt;code&gt;vcheck&lt;/code&gt;, a vulnerability checker that queries an API for CVEs affecting packages you specify. Along the way it covers every pattern you&amp;rsquo;ll need for a production-quality CLI: subcommands, persistent flags, config files, environment variables, structured output, graceful shutdown, testing, cross-compilation, and automated releases with GoReleaser.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zero Trust Architecture in Practice: Beyond the Buzzword</title>
      <link>/posts/zero-trust-architecture-in-practice/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zero-trust-architecture-in-practice/</guid>
      <description>&lt;p&gt;&amp;ldquo;Never trust, always verify&amp;rdquo; sounds simple until you try to implement it. Zero Trust Architecture (ZTA) has been a security industry buzzword for over a decade, but the core idea is sound and increasingly achievable without enterprise budgets: stop treating your network perimeter as a security boundary, because it no longer exists.&lt;/p&gt;&#xA;&lt;p&gt;Traditional security assumes everything inside the firewall is safe. A compromised laptop, a misconfigured service, or a malicious insider can move laterally across the entire internal network unchallenged. Zero Trust flips the model: every request is authenticated and authorized regardless of where it originates — inside the office, on VPN, or from a cloud function.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apache Kafka Deep Dive</title>
      <link>/posts/apache-kafka-deep-dive/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/apache-kafka-deep-dive/</guid>
      <description>&lt;p&gt;Apache Kafka is one of those systems that looks simple on the surface — a distributed log, messages in, messages out — until you run it in production and discover that the gap between &amp;ldquo;it works&amp;rdquo; and &amp;ldquo;it works correctly at scale under failure conditions&amp;rdquo; is vast. Kafka is built on a deceptively powerful abstraction: the &lt;strong&gt;immutable, ordered, replicated log&lt;/strong&gt;. Everything else flows from that.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers Kafka from the ground up: the internal architecture, producing and consuming messages with real code, partition strategy and consumer groups, the subtle correctness guarantees that separate at-most-once from exactly-once delivery, and deploying Kafka on Kubernetes with Strimzi.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BGP for Engineers: How the Internet Routes Itself</title>
      <link>/posts/bgp-for-engineers/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bgp-for-engineers/</guid>
      <description>&lt;p&gt;BGP is the protocol that holds the internet together. Every packet that crosses an autonomous system boundary is guided by BGP decisions. Yet for most engineers, BGP remains mysterious — something ISPs manage, not something you&amp;rsquo;d ever touch. That changes the moment you work on cloud infrastructure, build a multi-site network, or run a datacenter fabric. This guide cuts through the academic abstractions and gives you a working mental model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building in Public: Why Sharing Your Work Compounds Over Time</title>
      <link>/posts/building-in-public/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/building-in-public/</guid>
      <description>&lt;p&gt;There&amp;rsquo;s a particular kind of developer who consistently gets inbound job offers, consulting work, and interesting opportunities without actively looking for them. They&amp;rsquo;re not always the best coder in the room. They&amp;rsquo;re not necessarily prolific open source contributors. What they have in common is a body of public work — posts, projects, talks, documentation — that represents their thinking and their skills over time.&lt;/p&gt;&#xA;&lt;p&gt;Building in public is the practice of sharing what you&amp;rsquo;re working on, learning, and figuring out as you go. Not polished retrospectives or thought leadership. The in-progress stuff: the half-finished project, the thing you learned by debugging for three hours, the architecture decision you&amp;rsquo;re second-guessing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cloudflare Workers and the Edge: Building Globally Distributed Apps with Zero Cold Starts</title>
      <link>/posts/cloudflare-workers-and-the-edge/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/cloudflare-workers-and-the-edge/</guid>
      <description>&lt;p&gt;The conventional serverless model sends your code to a handful of regions and hopes users are nearby. Cloudflare Workers flips this: your code runs in 300+ cities worldwide, executing within milliseconds of every user on the planet. There are no cold starts in the traditional sense — Workers use V8 isolates instead of containers, spinning up in under a millisecond. And the pricing model is generous: 100,000 requests per day on the free tier, with paid plans at $0.30 per million requests.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Crossplane: Infrastructure as Kubernetes — Composites, Providers, and Replacing Terraform</title>
      <link>/posts/crossplane-infrastructure-as-kubernetes/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/crossplane-infrastructure-as-kubernetes/</guid>
      <description>&lt;p&gt;Terraform is the dominant infrastructure-as-code tool, but it has a fundamental limitation: it runs as a pipeline step, not a continuously running control loop. Once &lt;code&gt;terraform apply&lt;/code&gt; finishes, Terraform is done. If someone manually changes a resource, nothing detects it until the next apply. If a resource drifts or gets deleted, Terraform doesn&amp;rsquo;t react.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Crossplane&lt;/strong&gt; takes a different approach. It extends Kubernetes with custom resource definitions for every cloud resource — an S3 bucket is a &lt;code&gt;Bucket&lt;/code&gt; object, an RDS instance is a &lt;code&gt;RDSInstance&lt;/code&gt;, a VPC is a &lt;code&gt;VPC&lt;/code&gt;. Kubernetes controllers continuously reconcile declared state against actual state, exactly like they do for &lt;code&gt;Deployment&lt;/code&gt; and &lt;code&gt;Service&lt;/code&gt;. Drift is detected and corrected automatically. Resources are first-class Kubernetes objects, so all your GitOps tooling, RBAC, and observability works on infrastructure too.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Data Pipeline Patterns: ETL vs ELT, Streaming, Batch Processing, and Orchestration</title>
      <link>/posts/data-pipeline-patterns/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/data-pipeline-patterns/</guid>
      <description>&lt;p&gt;Data pipelines move data from where it&amp;rsquo;s created to where it&amp;rsquo;s useful. That sounds simple, but the engineering space between &amp;ldquo;data is here&amp;rdquo; and &amp;ldquo;data is useful over there&amp;rdquo; spans an enormous range of architectures, trade-offs, and failure modes. This guide cuts through the terminology and gives you a mental model for choosing between ETL and ELT, streaming and batch, and the orchestration tools that tie it all together.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-core-problem-data-is-created-where-its-not-useful&#34;&gt;The Core Problem: Data Is Created Where It&amp;rsquo;s Not Useful&lt;/h2&gt;&#xA;&lt;p&gt;Operational data lives in transactional databases — PostgreSQL, MySQL, MongoDB — optimized for fast reads and writes of individual records. Analytical work needs the opposite: scan millions of rows, aggregate across dimensions, join across sources. These workloads conflict. Running a complex analytical query against your production OLTP database slows down your users.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Database Migrations Without Downtime: Expand/Contract, Shadow Tables, and Safe Deploys</title>
      <link>/posts/database-migrations-without-downtime/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/database-migrations-without-downtime/</guid>
      <description>&lt;p&gt;Database migrations are the leading cause of unplanned downtime in web applications. Not because they&amp;rsquo;re inherently dangerous, but because most teams don&amp;rsquo;t have a systematic approach to making them safe. They write a migration, run it in staging, it works fine, they run it in production, and it locks the table for 45 seconds while 50,000 users experience timeouts.&lt;/p&gt;&#xA;&lt;p&gt;The good news: running schema changes on a live production database without downtime is entirely possible for nearly every operation. The approach is counter-intuitive — it requires splitting what feels like a single change into multiple coordinated steps across multiple deployments — but once you internalize the pattern, it becomes second nature.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Developer Portals with Backstage: Catalog, Scaffolding, TechDocs, and Plugins</title>
      <link>/posts/developer-portals-backstage/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/developer-portals-backstage/</guid>
      <description>&lt;p&gt;Backstage is an open-source developer portal framework built by Spotify and donated to the CNCF. It started as Spotify&amp;rsquo;s internal tool for managing thousands of microservices — a single place where any engineer could find what services existed, who owned them, where their documentation lived, and how to create a new one. Backstage was open-sourced in 2020 and is now the de facto standard for building internal developer portals.&lt;/p&gt;&#xA;&lt;p&gt;At its core, Backstage solves the &amp;ldquo;where does this live?&amp;rdquo; problem that plagues growing engineering organizations. Services scatter across GitHub repos, documentation hides in Confluence, runbooks live in Notion, and nobody knows what depends on what. Backstage pulls all of this into a single, searchable, maintained catalog — and builds self-service tooling on top of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Distributed Tracing with Tempo and Grafana: From Zero to TraceQL</title>
      <link>/posts/distributed-tracing-tempo-grafana/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/distributed-tracing-tempo-grafana/</guid>
      <description>&lt;h1 id=&#34;distributed-tracing-with-tempo-and-grafana-from-zero-to-traceql&#34;&gt;Distributed Tracing with Tempo and Grafana: From Zero to TraceQL&lt;/h1&gt;&#xA;&lt;p&gt;Distributed tracing answers the question every on-call engineer eventually asks: &amp;ldquo;What actually happened to that specific request?&amp;rdquo; Logs tell you events occurred. Metrics tell you how many times. Traces tell you &lt;em&gt;where the time went&lt;/em&gt; and &lt;em&gt;how services talked to each other&lt;/em&gt; for a single request&amp;rsquo;s journey through your system.&lt;/p&gt;&#xA;&lt;p&gt;Grafana Tempo is the purpose-built trace backend that integrates natively with Loki (logs) and Prometheus (metrics), enabling the &amp;ldquo;click a trace ID in a log line, jump to the full trace, click a metric exemplar, land on the same trace&amp;rdquo; workflow that makes incident investigation dramatically faster.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DPDK and High-Performance Networking: Kernel Bypass for Line-Rate Packet Processing</title>
      <link>/posts/dpdk-high-performance-networking/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dpdk-high-performance-networking/</guid>
      <description>&lt;p&gt;The Linux kernel network stack is an engineering marvel. It handles TCP, UDP, routing, firewalling, and a thousand edge cases safely and correctly. But &amp;ldquo;safe and correct&amp;rdquo; comes at a cost: system calls, context switches, interrupt handling, memory copies, and lock contention that add up to microseconds of latency per packet. At 10 Gbps, you&amp;rsquo;re receiving 14 million packets per second. The kernel stack can handle millions of packets per second per core under ideal conditions, but at 100 Gbps — 148 million pps — the math stops working.&lt;/p&gt;</description>
    </item>
    <item>
      <title>eBPF for Observability</title>
      <link>/posts/ebpf-for-observability/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ebpf-for-observability/</guid>
      <description>&lt;p&gt;eBPF is one of the most significant additions to the Linux kernel in the past decade. It lets you run sandboxed programs inside the kernel itself — attaching them to virtually any system event — without modifying kernel source code, loading a kernel module, or rebooting. The result is observability that was previously impossible or required invasive instrumentation: you can trace every system call, follow a network packet from NIC to socket, profile CPU usage at function-call granularity, and measure I/O latency histograms — all in production, with near-zero overhead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ephemeral Environments: Preview Deployments, Branch Environments, and Testing in Isolation</title>
      <link>/posts/ephemeral-environments/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ephemeral-environments/</guid>
      <description>&lt;p&gt;Every engineering team eventually hits the same wall: staging is a shared environment, it&amp;rsquo;s broken half the time, and no one is sure whose changes are on it. QA is blocked waiting for a stable build. Developers are afraid to push to staging because it&amp;rsquo;ll break someone else&amp;rsquo;s review. The staging database has a year&amp;rsquo;s worth of unreviewed test data in it. A hotfix needs testing but staging is occupied.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GitHub Actions Advanced Patterns: Reusable Workflows, Composite Actions, Matrix Builds, and Self-Hosted Runners</title>
      <link>/posts/github-actions-advanced-patterns/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/github-actions-advanced-patterns/</guid>
      <description>&lt;p&gt;Most teams start with GitHub Actions by copying a workflow YAML, wiring up a few steps, and calling it done. That works fine for a single repo. But as your organization grows — more services, more repos, more engineers — those ad-hoc workflows become a maintenance nightmare: duplicated logic across dozens of repos, inconsistent security practices, cache misses that slow everyone down, and flaky tests nobody can diagnose.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the patterns that make Actions scale: reusable workflows that centralize your CI standards, composite actions that compose building blocks, matrix strategies that parallelize intelligently, self-hosted runners that give you GPU access or private network reach, and the caching and security practices that turn a slow, fragile pipeline into a reliable engineering asset.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Go for DevOps Engineers</title>
      <link>/posts/go-for-devops-engineers/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/go-for-devops-engineers/</guid>
      <description>&lt;p&gt;Go is the language of infrastructure. Docker, Kubernetes, Terraform, Prometheus, Grafana, etcd, Vault, Consul, CockroachDB — the tools that run production systems are overwhelmingly written in Go. That&amp;rsquo;s not an accident. Go compiles to a single static binary with no runtime dependencies, has first-class concurrency primitives, starts in milliseconds, and produces lean containers. For DevOps engineers who want to move beyond Bash scripts and Python one-offs into tools that perform at scale, Go is the natural choice.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GPU Infrastructure for ML: CUDA, MIG, Kubernetes Device Plugins, and Cost-Efficient Training</title>
      <link>/posts/gpu-infrastructure-for-ml/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gpu-infrastructure-for-ml/</guid>
      <description>&lt;p&gt;GPUs are the most expensive line item in ML infrastructure budgets, and they&amp;rsquo;re routinely wasted. A survey of cloud GPU utilization finds average utilization hovering around 20-30% — meaning most organizations are paying for three or four GPUs to get the work of one. This guide covers how GPU infrastructure actually works, how to share GPUs efficiently across workloads in Kubernetes, and how to build training clusters that don&amp;rsquo;t hemorrhage money.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Incident Response Playbook</title>
      <link>/posts/incident-response-playbook/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/incident-response-playbook/</guid>
      <description>&lt;p&gt;An incident will happen. A database goes down, a deployment introduces a critical bug, an attacker gains access to a production system, a cloud region fails. The question isn&amp;rsquo;t whether you&amp;rsquo;ll face incidents — it&amp;rsquo;s whether you&amp;rsquo;ll face them with a plan or without one.&lt;/p&gt;&#xA;&lt;p&gt;Teams that handle incidents well share a common trait: they&amp;rsquo;ve thought through the process &lt;em&gt;before&lt;/em&gt; the incident. They have documented roles, communication channels, escalation paths, and runbooks. When everything is on fire at 2 AM, the last thing you want to be doing is figuring out the process.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Internal Developer Platforms: Building the Golden Path</title>
      <link>/posts/internal-developer-platforms/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/internal-developer-platforms/</guid>
      <description>&lt;p&gt;An Internal Developer Platform (IDP) is the sum of tools, workflows, and self-service capabilities that a platform team provides to product teams. It&amp;rsquo;s the difference between a developer waiting three days for a ticket to provision a staging database, and a developer running one command and having a database URL in their terminal thirty seconds later.&lt;/p&gt;&#xA;&lt;p&gt;This post is about building that — the concrete pieces, the abstractions, the tooling choices, and the patterns that make an IDP genuinely useful rather than an elaborate system that gets routed around.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IPv6 Practical Guide: Addressing, Dual-Stack, and Running IPv6 in Your Homelab</title>
      <link>/posts/ipv6-practical-guide/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ipv6-practical-guide/</guid>
      <description>&lt;p&gt;IPv4 exhaustion isn&amp;rsquo;t a future problem — it&amp;rsquo;s been the present reality for over a decade. IPv6 adoption crossed 40% of global internet traffic in 2024, and major cloud providers, CDNs, and mobile networks are largely IPv6-first. Yet many engineers still treat IPv6 as someone else&amp;rsquo;s concern. This guide is about making it yours — understanding the addressing model, configuring dual-stack, and running IPv6 confidently from your homelab to production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>K3s on Raspberry Pi and Homelab: Lightweight Kubernetes That Actually Works</title>
      <link>/posts/k3s-raspberry-pi-homelab/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/k3s-raspberry-pi-homelab/</guid>
      <description>&lt;p&gt;Kubernetes has a reputation for being operationally complex, resource-hungry, and overkill for anything smaller than a mid-sized company. K3s — the lightweight Kubernetes distribution from Rancher/SUSE — exists to challenge that reputation. It runs comfortably on a Raspberry Pi 4 with 4 GB of RAM, installs in about 30 seconds, and is fully conformant Kubernetes. The same &lt;code&gt;kubectl&lt;/code&gt; commands, the same manifests, the same Helm charts.&lt;/p&gt;&#xA;&lt;p&gt;This guide walks through standing up a K3s cluster on Raspberry Pi hardware (or any homelab server), connecting multiple nodes, configuring ingress and TLS, adding persistent storage with Longhorn, and deploying real workloads. By the end you&amp;rsquo;ll have a cluster that can run most things you&amp;rsquo;d run in a cloud Kubernetes environment, on hardware that fits in a shoebox.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Cost Optimization: Rightsizing, Spot Nodes, Bin Packing, Kubecost, and Scale-to-Zero</title>
      <link>/posts/kubernetes-cost-optimization/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-cost-optimization/</guid>
      <description>&lt;p&gt;Kubernetes makes it easy to over-provision. Default resource requests are conservative, autoscalers react slowly, and nobody deletes staging workloads on Friday afternoon. The result: clusters running at 20-30% utilization while the cloud bill climbs. This guide covers the full stack of cost optimization — from understanding what you&amp;rsquo;re paying for, to the tools that cut waste without breaking production.&lt;/p&gt;&#xA;&lt;h2 id=&#34;understanding-where-the-money-goes&#34;&gt;Understanding Where the Money Goes&lt;/h2&gt;&#xA;&lt;p&gt;Before optimizing, instrument. Cloud Kubernetes costs break down into three main buckets:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Networking Internals: kube-proxy, iptables vs eBPF, CNI Plugins, and DNS</title>
      <link>/posts/kubernetes-networking-internals/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-networking-internals/</guid>
      <description>&lt;p&gt;Kubernetes networking has a reputation for being mysterious. Services seem to magically route traffic to pods, DNS names resolve to cluster IPs that don&amp;rsquo;t exist on any interface, and yet somehow packets find their way. This guide tears open the black box: how the pod network model works, what kube-proxy actually does with iptables, how eBPF is replacing it, what CNI plugins do, and how CoreDNS resolves names inside the cluster.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Operators Deep Dive</title>
      <link>/posts/kubernetes-operators-deep-dive/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-operators-deep-dive/</guid>
      <description>&lt;p&gt;Kubernetes operators are the mechanism by which Kubernetes becomes a platform for anything, not just containers. An operator is a controller that extends the Kubernetes API with custom resource types and encodes the operational knowledge for running a specific piece of software — the same knowledge a human operator would use, but expressed as code.&lt;/p&gt;&#xA;&lt;p&gt;The Operator pattern is powerful but often poorly implemented in practice. Most tutorials show a toy reconciler that prints a log line. Real operators need to handle partial failure, track status accurately, clean up resources on deletion, run exactly one reconciler at a time in a cluster, and be testable without a running cluster. This guide covers all of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Hardening Checklist</title>
      <link>/posts/linux-hardening-checklist/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-hardening-checklist/</guid>
      <description>&lt;p&gt;A freshly installed Linux server is not a secure Linux server. The default configuration optimises for compatibility and ease of use, not for defence in depth. Hardening is the process of reducing the attack surface: removing unnecessary services, enforcing least privilege, enabling auditing, and configuring mandatory access controls.&lt;/p&gt;&#xA;&lt;p&gt;This guide walks through hardening a Linux server systematically — following CIS Benchmark principles, configuring auditd for forensic-quality logging, setting up AppArmor (Ubuntu/Debian) or SELinux (RHEL/Rocky), tuning kernel parameters, and measuring your progress with Lynis.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Namespaces and cgroups: The Kernel Primitives That Make Containers Possible</title>
      <link>/posts/linux-namespaces-cgroups/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-namespaces-cgroups/</guid>
      <description>&lt;p&gt;When you run &lt;code&gt;docker run nginx&lt;/code&gt;, something remarkable happens in about 300 milliseconds: a new isolated execution environment appears, with its own process tree, its own network stack, its own filesystem view, and its own resource limits — all without a hypervisor, without booting a kernel, without hardware virtualization.&lt;/p&gt;&#xA;&lt;p&gt;This is made possible by two Linux kernel features: &lt;strong&gt;namespaces&lt;/strong&gt; and &lt;strong&gt;cgroups&lt;/strong&gt;. Container runtimes like Docker, containerd, and podman are, at their core, orchestrators that configure these two kernel primitives and then execute your process inside them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MLOps Fundamentals: Experiment Tracking, Model Registry, Serving, and Drift Monitoring</title>
      <link>/posts/mlops-fundamentals/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mlops-fundamentals/</guid>
      <description>&lt;p&gt;A model that performs well in a notebook is a science project. A model that performs well in production six months after deployment is engineering. The gap between the two is MLOps: the practices, tooling, and culture that make machine learning reproducible, deployable, and maintainable at scale.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the core MLOps pillars — experiment tracking so you can reproduce any result, a model registry so you know what&amp;rsquo;s in production and why, model serving infrastructure that handles real traffic, and drift monitoring so you know when your model stops working before your users do.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Multi-Cluster Kubernetes: Fleet Management, Cross-Cluster Service Discovery, and Traffic Routing</title>
      <link>/posts/multi-cluster-kubernetes/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/multi-cluster-kubernetes/</guid>
      <description>&lt;p&gt;Single-cluster Kubernetes gets you surprisingly far. Many organizations run production workloads on one cluster for years without hitting fundamental limits. But there are real reasons to run multiple clusters — regulatory data residency, fault isolation, team autonomy, blast radius reduction, and geographic distribution. When those reasons apply, multi-cluster architecture introduces a new set of hard problems.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the core patterns: why multi-cluster, how to provision and manage a fleet with Cluster API, how to distribute workloads with Karmada, and how to handle the genuinely difficult problems of cross-cluster service discovery and traffic routing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Network Observability with Cilium and Hubble: Complete Visibility Into Your Kubernetes Network</title>
      <link>/posts/network-observability-cilium-hubble/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/network-observability-cilium-hubble/</guid>
      <description>&lt;p&gt;One of the hardest problems in Kubernetes networking is answering a simple question: &lt;em&gt;why can&amp;rsquo;t pod A talk to pod B?&lt;/em&gt; Traditional network debugging means guessing at iptables rules, running tcpdump inside containers, and piecing together what happened after the fact. Cilium and Hubble take a fundamentally different approach — using eBPF to observe every network flow at the kernel level, with identity-aware visibility that understands Kubernetes labels, namespaces, and DNS names rather than just IP addresses.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NFS and Network Storage: A Complete Guide from Homelab to the Cloud</title>
      <link>/posts/nfs-and-network-storage/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nfs-and-network-storage/</guid>
      <description>&lt;p&gt;Network storage is how you stop caring which physical machine your data lives on. Whether you&amp;rsquo;re sharing a media library across three Raspberry Pis, providing shared storage to a Kubernetes cluster, or running a high-performance computing workload that needs parallel I/O across dozens of nodes, the answer is some form of network-attached storage with a protocol that matches the access pattern.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the full landscape: the protocols (NFS, SMB, iSCSI), the distributed filesystems (Lustre, Ceph), and how all of it maps to both homelab deployments and cloud services on Azure, AWS, and GCP. By the end you&amp;rsquo;ll be able to match any storage requirement to the right protocol and deployment model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nix and NixOS for Developers: Reproducible Environments, Flakes, and devShells</title>
      <link>/posts/nix-nixos-for-developers/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nix-nixos-for-developers/</guid>
      <description>&lt;p&gt;Every developer has lived this story: you clone a repo, run the setup script, spend two hours debugging version conflicts, discover the README assumes Ubuntu 20.04 when you&amp;rsquo;re on 22.04, and eventually get something working that&amp;rsquo;s subtly different from what CI uses. Six months later, a new team member goes through the same ritual.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Nix&lt;/strong&gt; solves this by making environments reproducible at the package manager level. A Nix expression specifies exact versions and dependencies — not &amp;ldquo;python &amp;gt;= 3.11&amp;rdquo; but a cryptographic hash identifying a specific build. Every developer who applies the same expression gets byte-for-byte identical tooling, regardless of what else is on their machine, what OS they run, or when they set it up.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Object Storage Internals: How S3-Compatible Storage Works and Self-Hosting with MinIO</title>
      <link>/posts/object-storage-internals/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/object-storage-internals/</guid>
      <description>&lt;p&gt;Object storage has become the default substrate for data at rest. Backups, ML training data, media files, data lake archives, container image layers, Terraform state — all of it flows through S3-compatible APIs. Most engineers interact with object storage as a black box: you &lt;code&gt;PUT&lt;/code&gt; an object, you &lt;code&gt;GET&lt;/code&gt; it back, done. But understanding how it actually works — consistency guarantees, durability mechanisms, performance characteristics — makes you dramatically better at choosing the right architecture and debugging the inevitable surprises.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenTelemetry in Practice: Instrumentation, the Collector, and Connecting to Your Observability Stack</title>
      <link>/posts/opentelemetry-in-practice/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/opentelemetry-in-practice/</guid>
      <description>&lt;p&gt;Observability used to mean wiring three separate systems: a metrics library, a tracing SDK, and a logging framework — each with its own agent, its own wire format, and its own vendor lock-in. &lt;strong&gt;OpenTelemetry&lt;/strong&gt; (OTel) changes this by providing a single, vendor-neutral API and SDK for all three signals, plus a standalone &lt;strong&gt;Collector&lt;/strong&gt; daemon that decouples your application from your backends.&lt;/p&gt;&#xA;&lt;p&gt;This guide goes from zero to a working OTel pipeline: instrumenting apps in Python, Go, and Node.js; building a Collector configuration that processes and routes telemetry; and connecting everything to Jaeger, Tempo, Prometheus, and Loki.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OWASP API Security Top 10: A Practical Guide to Securing Your APIs</title>
      <link>/posts/owasp-api-security-top-10/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/owasp-api-security-top-10/</guid>
      <description>&lt;h1 id=&#34;owasp-api-security-top-10-a-practical-guide-to-securing-your-apis&#34;&gt;OWASP API Security Top 10: A Practical Guide to Securing Your APIs&lt;/h1&gt;&#xA;&lt;p&gt;APIs are the backbone of modern software. They power mobile apps, enable third-party integrations, and connect microservices. They&amp;rsquo;re also the primary attack surface for modern applications — the &lt;a href=&#34;https://www.verizon.com/business/resources/reports/dbir/&#34;&gt;Verizon Data Breach Investigations Report&lt;/a&gt; consistently shows that web application attacks (APIs included) are the leading cause of breaches.&lt;/p&gt;&#xA;&lt;p&gt;The OWASP API Security Top 10 was created specifically because traditional web application vulnerabilities don&amp;rsquo;t fully capture what goes wrong with APIs. An API doesn&amp;rsquo;t render HTML, so XSS is less relevant. But an API that exposes every field of your user table because a developer returned &lt;code&gt;user.*&lt;/code&gt; instead of specific fields? That happens constantly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Penetration Testing Your Homelab</title>
      <link>/posts/penetration-testing-homelab/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/penetration-testing-homelab/</guid>
      <description>&lt;p&gt;Your homelab is a perfect environment to learn offensive security techniques — you own the infrastructure, you control the scope, and breaking something doesn&amp;rsquo;t cost you a production outage. Pentesting your own homelab is one of the fastest ways to build a genuine understanding of attack surfaces, and it turns vague security advice (&amp;ldquo;patch your systems&amp;rdquo;) into concrete findings (&amp;ldquo;your Grafana instance is running 9.0.1 with CVE-2021-43798 exposed&amp;rdquo;).&lt;/p&gt;&#xA;&lt;p&gt;This guide covers a structured approach to homelab pentesting: setting up Kali Linux safely, reconnaissance with nmap, vulnerability scanning, web application testing, and using Metasploit responsibly — all against infrastructure you own.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Platform Engineering vs DevOps: What Changed and Why It Matters</title>
      <link>/posts/platform-engineering-vs-devops/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/platform-engineering-vs-devops/</guid>
      <description>&lt;p&gt;Every few years, the industry rebrands how it thinks about the relationship between software delivery and infrastructure operations. SRE replaced classic ops. DevOps dissolved the wall between dev and ops. Now Platform Engineering is being positioned as the next evolution. The cynical read is that it&amp;rsquo;s the same work with a new name and a shinier conference circuit.&lt;/p&gt;&#xA;&lt;p&gt;The more accurate read: Platform Engineering addresses a real failure mode of DevOps at scale — one that&amp;rsquo;s easy to miss when you have two teams but becomes painful when you have twenty.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL for Developers: Indexes, EXPLAIN ANALYZE, JSONB, and Tuning for Real Workloads</title>
      <link>/posts/postgresql-for-developers/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/postgresql-for-developers/</guid>
      <description>&lt;p&gt;PostgreSQL is one of those tools where the gap between &amp;ldquo;uses it&amp;rdquo; and &amp;ldquo;understands it&amp;rdquo; is enormous. Most application developers use Postgres as a black box: write SQL, get results. That works until it doesn&amp;rsquo;t — until a query takes 30 seconds, a table grows to 100 million rows, or you need to model data that doesn&amp;rsquo;t fit neatly into columns.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the parts of Postgres that actually matter for developers building real applications: how indexes work and which type to use when, how to read &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; output to understand what Postgres is actually doing, JSONB for flexible semi-structured data, and the configuration tuning that moves the needle on real workloads.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pre-commit Hooks and Code Quality Gates: Enforcing Standards Before They Become Problems</title>
      <link>/posts/pre-commit-hooks-and-code-quality-gates/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pre-commit-hooks-and-code-quality-gates/</guid>
      <description>&lt;p&gt;Code review is expensive. A reviewer who has to point out that a function is missing a type annotation, that a secret is hardcoded, or that the import order is wrong is a reviewer who isn&amp;rsquo;t reviewing logic, architecture, or correctness. Automated quality gates eliminate entire categories of review feedback before a PR is even opened.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;strong&gt;pre-commit&lt;/strong&gt; framework is the standard tool for managing git hooks across a team. One YAML file configures dozens of linters, formatters, and security scanners in a reproducible way. Every contributor gets the same checks, running against only the files they changed, with no global tool installation required.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Python Packaging and Distribution: pyproject.toml, uv, Wheels, PyPI, and Vendoring</title>
      <link>/posts/python-packaging-and-distribution/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/python-packaging-and-distribution/</guid>
      <description>&lt;p&gt;Python packaging has a reputation for being confusing, and historically that reputation was earned. &lt;code&gt;setup.py&lt;/code&gt;, &lt;code&gt;setup.cfg&lt;/code&gt;, &lt;code&gt;requirements.txt&lt;/code&gt;, &lt;code&gt;Pipfile&lt;/code&gt;, &lt;code&gt;poetry.lock&lt;/code&gt;, &lt;code&gt;MANIFEST.in&lt;/code&gt; — a graveyard of standards each solving one problem while creating two more. The good news: the ecosystem has largely converged. &lt;code&gt;pyproject.toml&lt;/code&gt; is the standard configuration file. &lt;code&gt;uv&lt;/code&gt; has emerged as the fastest and most ergonomic tool for the full workflow. This guide covers modern Python packaging from development environment to published package.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust for Systems Programming: Ownership, Safety, and Where It Beats C/C&#43;&#43;</title>
      <link>/posts/rust-for-systems-programming/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rust-for-systems-programming/</guid>
      <description>&lt;p&gt;Rust has crossed from interesting experiment to production necessity. The Linux kernel accepted Rust in 2022. Android uses Rust for new system components. Microsoft rewrites Windows security-critical code in Rust. The NSA and CISA recommend Rust as a memory-safe alternative to C and C++. Behind the hype is a language that genuinely solves problems that have cost the industry billions of dollars in CVEs, crashes, and debugging time.&lt;/p&gt;&#xA;&lt;p&gt;This guide is for engineers who already program — in Go, Python, C, or C++ — and want to understand what Rust actually does differently, when it&amp;rsquo;s worth the learning curve, and how to write real code in it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secrets Management with HashiCorp Vault</title>
      <link>/posts/secrets-management-vault/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/secrets-management-vault/</guid>
      <description>&lt;p&gt;Every application needs secrets: database passwords, API keys, TLS certificates, cloud credentials. The default approach — hardcoding them in config files, storing them in environment variables baked into Docker images, or passing them through CI/CD environment variables — works until it doesn&amp;rsquo;t. Secrets leak into git history, get committed in &lt;code&gt;.env&lt;/code&gt; files, show up in build logs, and outlive their usefulness by years.&lt;/p&gt;&#xA;&lt;p&gt;HashiCorp Vault solves this systematically. It&amp;rsquo;s a secrets engine, a certificate authority, an encryption service, and an identity broker — all in one. This guide covers running Vault in production, the secrets engines you&amp;rsquo;ll use most, authenticating your workloads, and integrating with Kubernetes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Self-Hosted AI Inference: vLLM, llama.cpp, and Running Your Own OpenAI-Compatible API</title>
      <link>/posts/self-hosted-ai-inference/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/self-hosted-ai-inference/</guid>
      <description>&lt;p&gt;Running your own LLM inference stack used to require a research budget and a team of ML engineers. Today, tools like &lt;strong&gt;vLLM&lt;/strong&gt; and &lt;strong&gt;llama.cpp&lt;/strong&gt; let you run production-grade inference on hardware ranging from a single consumer GPU to a multi-node cluster — with an OpenAI-compatible API so existing code works unchanged.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the full stack: engine architecture, deployment patterns, quantization trade-offs, batching mechanics, and how to benchmark throughput so you know what you&amp;rsquo;re actually getting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Service Meshes with Istio and Linkerd</title>
      <link>/posts/service-meshes-istio-linkerd/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/service-meshes-istio-linkerd/</guid>
      <description>&lt;p&gt;A service mesh is one of those technologies that sounds like a solution looking for a problem — until you&amp;rsquo;re running dozens of microservices and realize you&amp;rsquo;ve re-implemented retry logic, timeout handling, circuit breaking, and mutual TLS in seven different languages across fifteen teams. The mesh moves that infrastructure concern out of your application code and into the platform.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers what a service mesh actually does, when you genuinely need one (and when you don&amp;rsquo;t), and how to use the two leading options — &lt;strong&gt;Istio&lt;/strong&gt; and &lt;strong&gt;Linkerd&lt;/strong&gt; — for the things that matter most: mTLS between services, traffic splitting for canary deployments, and deep observability without touching application code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SLOs and Error Budgets: The Engineering Discipline Behind Reliable Services</title>
      <link>/posts/slos-and-error-budgets/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/slos-and-error-budgets/</guid>
      <description>&lt;p&gt;Reliability is a feature. But unlike most features, it competes directly with velocity — every hour spent hardening a service is an hour not spent shipping new functionality. &lt;strong&gt;Service Level Objectives (SLOs)&lt;/strong&gt; resolve this tension by making reliability a negotiated contract: you agree on how reliable a service needs to be, you measure it honestly, and the remaining headroom becomes your &lt;strong&gt;error budget&lt;/strong&gt; — the allowance for risk-taking.&lt;/p&gt;&#xA;&lt;p&gt;This isn&amp;rsquo;t abstract theory. SLOs are how Google, Netflix, and Shopify manage hundreds of services with small teams. This guide covers the complete lifecycle: defining meaningful SLIs, setting defensible SLOs, computing error budgets, wiring up burn rate alerts that work, and running SLO reviews that actually change behavior.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLite in Production: When It&#39;s the Right Choice, WAL Mode, Backups, and Litestream Replication</title>
      <link>/posts/sqlite-in-production/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sqlite-in-production/</guid>
      <description>&lt;p&gt;SQLite has a reputation problem. Most developers learned it as the toy database — the thing you use in mobile apps, unit tests, and prototypes before graduating to a &amp;ldquo;real&amp;rdquo; database like PostgreSQL or MySQL. The assumption is that SQLite doesn&amp;rsquo;t belong in production.&lt;/p&gt;&#xA;&lt;p&gt;That assumption is wrong in a specific and interesting way. SQLite is the most widely deployed database engine in the world — it runs in every Android phone, every iPhone, every browser, every macOS and Windows installation, and billions of embedded devices. The SQLite authors estimate it handles more database queries per day than all other database engines combined.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Supply Chain Security: SBOMs, Sigstore, Cosign, and SLSA</title>
      <link>/posts/supply-chain-security/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/supply-chain-security/</guid>
      <description>&lt;p&gt;The SolarWinds breach. The Log4Shell vulnerability. The xz-utils backdoor. What these incidents have in common is that the attack didn&amp;rsquo;t come through the front door — it came through the software supply chain. Trusted code, from trusted sources, delivered through trusted update mechanisms, was weaponised against the people trusting it.&lt;/p&gt;&#xA;&lt;p&gt;Software supply chain security is the discipline of knowing exactly what&amp;rsquo;s in your software, verifying it was built the way it claims, and detecting when something unexpected slips in. This guide covers the four pillars of modern supply chain security: &lt;strong&gt;SBOMs&lt;/strong&gt; (knowing what you have), &lt;strong&gt;Sigstore/Cosign&lt;/strong&gt; (proving who built it and that it hasn&amp;rsquo;t been tampered with), &lt;strong&gt;SLSA&lt;/strong&gt; (attesting how it was built), and integrating all of this into CI/CD.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Talos Linux: The Immutable, API-Driven Kubernetes OS with No SSH</title>
      <link>/posts/talos-linux-immutable-kubernetes-os/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/talos-linux-immutable-kubernetes-os/</guid>
      <description>&lt;p&gt;Every Kubernetes node runs Linux. But most of those Linux installations are general-purpose operating systems — Ubuntu, CentOS, Debian — carrying decades of legacy: SSH daemons, package managers, shells, cron jobs, and hundreds of userspace binaries your Kubernetes workloads never need. Each of those components is an attack surface, a configuration drift opportunity, and a maintenance burden.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Talos Linux&lt;/strong&gt; strips the OS down to exactly what Kubernetes requires and nothing more. There is no SSH. There is no shell. There is no package manager. The entire OS is read-only and immutable — every node boots from the same image, and configuration is applied via a typed API over mTLS. When something needs to change, you update a machine config and Talos applies it atomically, without any manual intervention on the node.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Temporal for Durable Workflows: Replacing Fragile Cron Jobs and Distributed Sagas</title>
      <link>/posts/temporal-durable-workflows/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/temporal-durable-workflows/</guid>
      <description>&lt;p&gt;Every sufficiently complex backend has a graveyard of half-finished jobs. A payment that got charged but the fulfillment email never sent. An order stuck in &amp;ldquo;processing&amp;rdquo; because a retry loop silently died at 2am. A data pipeline that ran successfully on Monday but nobody noticed it failed on Tuesday because the cron job exited without alerting.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Temporal&lt;/strong&gt; solves this class of problem at the root. It&amp;rsquo;s a durable execution engine: you write ordinary code, and Temporal guarantees it runs to completion — even across process restarts, network failures, server crashes, and deployments. If a worker dies mid-workflow, Temporal replays the workflow from its event history on any available worker. No message queues to manage, no dead-letter queues to monitor, no custom retry logic to maintain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Time-Series Data with InfluxDB and TimescaleDB</title>
      <link>/posts/time-series-influxdb-timescaledb/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/time-series-influxdb-timescaledb/</guid>
      <description>&lt;p&gt;Time-series data is everywhere: server metrics, IoT sensors, financial ticks, application traces. It&amp;rsquo;s data where &lt;strong&gt;time is the primary axis&lt;/strong&gt; — you&amp;rsquo;re always asking &amp;ldquo;what happened at &lt;em&gt;this&lt;/em&gt; point in time?&amp;rdquo; or &amp;ldquo;what was the trend &lt;em&gt;over this window&lt;/em&gt;?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;General-purpose databases can handle time-series data at small scale, but they struggle once you start ingesting millions of data points per second. Specialized time-series databases solve this with storage formats, compression algorithms, and query primitives purpose-built for temporal data.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vector Databases in Production: Pinecone, Weaviate, Qdrant, and pgvector</title>
      <link>/posts/vector-databases-in-production/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vector-databases-in-production/</guid>
      <description>&lt;p&gt;The explosion of LLM-powered applications has made vector search a core infrastructure primitive. Semantic search, RAG (retrieval-augmented generation), recommendation systems, duplicate detection, anomaly detection — all of these reduce to the same operation: given a query vector, find the N most similar vectors in a large collection. Vector databases are purpose-built for this.&lt;/p&gt;&#xA;&lt;p&gt;This guide explains how vector search works under the hood, when each database is the right choice, and how to run vector search in production without surprises.&lt;/p&gt;</description>
    </item>
    <item>
      <title>WebAssembly Beyond the Browser: WASI, Kubernetes Sidecars, Spin, and the Future of Serverless</title>
      <link>/posts/webassembly-beyond-the-browser/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/webassembly-beyond-the-browser/</guid>
      <description>&lt;p&gt;WebAssembly started as a way to run near-native code in browsers. Then something interesting happened: the same properties that make it valuable in browsers — sandboxed execution, language-agnostic compilation target, deterministic behavior, tiny footprint — turned out to be exactly what server-side infrastructure needed too. If containers solved the &amp;ldquo;it works on my machine&amp;rdquo; problem, WebAssembly aims to solve it more completely: a single binary that runs identically on any architecture, any OS, in any environment, with a startup time measured in microseconds rather than seconds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ZFS for Homelabbers: Datasets, Snapshots, Send/Receive Replication, and Scrub Schedules</title>
      <link>/posts/zfs-for-homelabbers/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zfs-for-homelabbers/</guid>
      <description>&lt;p&gt;If you store data you care about in a homelab — media libraries, backups, VM images, documents — ZFS is worth learning. Not because it&amp;rsquo;s fashionable, but because it solves the real problems that matter for data integrity over years: silent corruption, failed disks, accidental deletion, and the slow drift of a filesystem away from a known-good state.&lt;/p&gt;&#xA;&lt;p&gt;ZFS is a combined volume manager and filesystem that was designed from the beginning around one principle: the data you read must be the data that was written. Every block has a checksum. Every read verifies it. A pool of drives is managed atomically — no split-brain, no inconsistent state after a power loss. Snapshots are instantaneous and space-efficient. Replication is built in at the filesystem level.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Alerting That Doesn&#39;t Burn You Out: Fighting Alert Fatigue and Building Sane On-Call</title>
      <link>/posts/alerting-without-burnout/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/alerting-without-burnout/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s 2:47 AM. Your phone screams. You grab it, squint at the screen: &lt;code&gt;HighMemoryUsage on prod-web-03&lt;/code&gt;. You silence it and go back to sleep. An hour later: &lt;code&gt;HighMemoryUsage on prod-web-04&lt;/code&gt;. Silence. Then at 4:15 AM: &lt;code&gt;CheckoutServiceDown&lt;/code&gt;. You silence that one too — and miss the actual incident that&amp;rsquo;s been bleeding revenue since 4:11.&lt;/p&gt;&#xA;&lt;p&gt;That sequence is alert fatigue. And it&amp;rsquo;s not a hypothetical. It&amp;rsquo;s happening on your team right now if your pager fires more than a few times per night and engineers are treating it like a snooze button.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ansible Playbooks: Idempotent Configuration Management at Any Scale</title>
      <link>/posts/ansible-playbooks/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ansible-playbooks/</guid>
      <description>&lt;p&gt;At some point, every sysadmin and homelabber reaches the same inflection point. You&amp;rsquo;ve got a handful of servers running various services, and every time you spin up a new one, you&amp;rsquo;re re-running the same steps from memory: create a user, copy your SSH key, install a bunch of packages, configure the firewall, tweak sshd_config. You either have a checklist in a notes app or you just wing it and hope you don&amp;rsquo;t miss anything.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automating Homelab Tasks with n8n: Visual Workflow Automation Self-Hosted</title>
      <link>/posts/automating-homelab-n8n/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/automating-homelab-n8n/</guid>
      <description>&lt;p&gt;If you have a homelab, you almost certainly have a sprawl of services talking past each other. Uptime Kuma knows when something is down, but nothing tells Telegram. Your nightly Restic backup runs, but nothing confirms it worked. A Home Assistant sensor fires, but the alert arrives with zero context. The glue that ties these services together usually ends up being a graveyard of bash scripts, systemd timers, and cron jobs you wrote six months ago and no longer fully trust.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bare Metal Provisioning: PXE Boot, iPXE, and Fully Automated OS Installs</title>
      <link>/posts/bare-metal-provisioning/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bare-metal-provisioning/</guid>
      <description>&lt;p&gt;Somewhere in most homelabbers&amp;rsquo; histories is a cardboard box of USB drives, each labeled in marker — &amp;ldquo;Ubuntu 22.04,&amp;rdquo; &amp;ldquo;Debian 12,&amp;rdquo; &amp;ldquo;Proxmox 8.1 (old).&amp;rdquo; Adding a new machine means hunting down the right drive, plugging it in, clicking through an installer, answering the same twenty questions you&amp;rsquo;ve answered a hundred times, and waiting. For one machine that&amp;rsquo;s an annoyance. For five machines it&amp;rsquo;s a Saturday. For fifty it&amp;rsquo;s a job.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bash Scripting Patterns That Hold Up in Production</title>
      <link>/posts/bash-scripting-patterns/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bash-scripting-patterns/</guid>
      <description>&lt;p&gt;Most Bash scripts start the same way: someone needs to automate one thing, writes ten lines, it works, and then three months later it&amp;rsquo;s running in CI, being sourced by other scripts, and nobody remembers what it does. This guide covers the patterns that keep scripts maintainable, debuggable, and safe when that happens.&lt;/p&gt;&#xA;&lt;h2 id=&#34;start-every-script-the-same-way&#34;&gt;Start Every Script the Same Way&lt;/h2&gt;&#xA;&lt;p&gt;These four lines should open every non-trivial script:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -euo pipefail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IFS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;$&amp;#39;\n\t&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;what-each-does&#34;&gt;What each does&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;&lt;/strong&gt; — Uses &lt;code&gt;env&lt;/code&gt; to find bash rather than hardcoding &lt;code&gt;/bin/bash&lt;/code&gt;. More portable across macOS, Linux, and NixOS where bash may live elsewhere.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Container Image Hardening: Distroless, Multi-Stage Builds, and Vulnerability Scanning</title>
      <link>/posts/container-image-hardening/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/container-image-hardening/</guid>
      <description>&lt;p&gt;The average developer pulls &lt;code&gt;node:latest&lt;/code&gt;, writes a Dockerfile, ships it, and moves on. Inside that image lives a full Debian environment: a shell, a package manager, curl, wget, compilers, and hundreds of packages that your application never touches at runtime. Every one of those packages is a potential CVE. Every installed binary is a pivot point for an attacker who achieves code execution.&lt;/p&gt;&#xA;&lt;p&gt;Container image hardening is the practice of aggressively narrowing what ends up in your production images. The goal is deceptively simple: &lt;strong&gt;ship only what the application needs to run — nothing more.&lt;/strong&gt; This post covers the full toolkit: multi-stage builds, distroless base images, Trivy scanning, Cosign signing, and the Kubernetes runtime controls that complete the picture.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dependency Management: Lock Files, Vulnerability Scanning, and Keeping Deps Fresh Without Pain</title>
      <link>/posts/dependency-management/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dependency-management/</guid>
      <description>&lt;p&gt;Dependency management is one of those topics that everyone knows matters and almost nobody handles systematically until something breaks badly. A critical CVE in a transitive dependency, a breaking change that slipped in under a minor version bump, or an update that broke prod on a Friday afternoon — these are the moments that turn &amp;ldquo;we should really set up automated dependency updates&amp;rdquo; from a backlog item into a war room priority.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Disaster Recovery Planning: RTO, RPO, Runbooks, and Actually Testing Your Backups</title>
      <link>/posts/disaster-recovery-planning/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/disaster-recovery-planning/</guid>
      <description>&lt;p&gt;A backup you haven&amp;rsquo;t tested is not a backup. It&amp;rsquo;s a hope.&lt;/p&gt;&#xA;&lt;p&gt;That distinction matters enormously at 2am when your primary database is gone, your storage array is throwing errors you&amp;rsquo;ve never seen before, and you&amp;rsquo;re trying to remember if you ever actually verified that the weekly backup job ran successfully. Most people have backups configured. Very few have disaster recovery.&lt;/p&gt;&#xA;&lt;p&gt;Backups are an input. Disaster recovery is the process — the documented, tested, rehearsed sequence of steps that gets your systems back to a known-good state within a time window your organization can survive. This guide covers what that actually means: how to define your recovery targets, classify your systems, build real runbooks, inject controlled failures through chaos engineering, and most importantly, test your restores before you need them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker Compose for Homelab: Multi-Service Stacks Done Right</title>
      <link>/posts/docker-compose-homelab/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/docker-compose-homelab/</guid>
      <description>&lt;p&gt;Running a single Docker container from the command line is easy. Running twenty interconnected services across a media stack, a monitoring stack, a reverse proxy, and a handful of self-hosted web apps — and being able to tear them all down, migrate them to a new machine, and bring them back up in minutes — is a different problem entirely. That&amp;rsquo;s exactly the problem Docker Compose was built to solve.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Feature Flags: Safe Deployments, Dark Launches, and Rolling Rollouts</title>
      <link>/posts/feature-flags/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/feature-flags/</guid>
      <description>&lt;p&gt;Every deployment is a risk event. Something that worked in staging breaks in production. A new checkout flow confuses users. A database query that ran fast on 1,000 rows crawls on 10 million. The classic response is to slow down deployments — review more, test more, deploy less often. Feature flags take the opposite approach: deploy constantly, but control what users actually see through configuration rather than code.&lt;/p&gt;&#xA;&lt;p&gt;This post covers the full lifecycle of feature flags, from a minimal PostgreSQL toggle table to production-grade platforms like Unleash and LaunchDarkly, with working code examples in Python, Go, and TypeScript.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fine-Tuning Small Models: When and Why to Fine-Tune vs. Prompt Engineer</title>
      <link>/posts/fine-tuning-small-models/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/fine-tuning-small-models/</guid>
      <description>&lt;p&gt;The phrase &amp;ldquo;fine-tune your model&amp;rdquo; sounds like the kind of thing that requires a PhD, a cluster of A100s, and six months of runway. In practice, you can meaningfully fine-tune a 7B or 8B parameter model on a consumer GPU in an afternoon, using open-source tooling, and deploy the result on the same laptop you use for everything else.&lt;/p&gt;&#xA;&lt;p&gt;The harder question isn&amp;rsquo;t &amp;ldquo;how do I fine-tune?&amp;rdquo; — it&amp;rsquo;s &amp;ldquo;should I fine-tune, and what for?&amp;rdquo; Fine-tuning is frequently the wrong tool. It&amp;rsquo;s also sometimes the only tool that works. Understanding the difference saves a lot of wasted effort.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Gaming on Linux in 2026: Better Than You Think</title>
      <link>/posts/gaming-on-linux/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gaming-on-linux/</guid>
      <description>&lt;p&gt;Five years ago, Linux gaming was a hobby for the determined. Today it&amp;rsquo;s a genuine platform. Valve&amp;rsquo;s investment in Proton, the Steam Deck&amp;rsquo;s commercial success, and an accelerating driver ecosystem have changed the equation. Over 80% of the Steam library runs on Linux without modification, AAA titles launch day-and-date with Windows ports, and many games actually perform better under Linux than on Windows due to leaner system overhead.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the current state of Linux gaming, the tools that make it work, and how to get the best performance out of your setup.&lt;/p&gt;</description>
    </item>
    <item>
      <title>GitOps with Flux and ArgoCD: Declarative Deployments Driven by Git</title>
      <link>/posts/gitops-flux-argocd/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/gitops-flux-argocd/</guid>
      <description>&lt;p&gt;There is a moment every Kubernetes operator eventually hits. You have a cluster running a dozen services. Things are humming along. Then you ssh into a node, run &lt;code&gt;kubectl apply -f&lt;/code&gt; to push a quick fix, and forget to update the YAML file in your repo. Three weeks later, someone (probably you) wonders why the running deployment doesn&amp;rsquo;t match the manifest on disk. The cluster has drifted from what you think it is.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Helm Charts: Packaging, Templating, and Managing Kubernetes Applications</title>
      <link>/posts/helm-charts/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/helm-charts/</guid>
      <description>&lt;p&gt;Raw Kubernetes manifests work fine when you have three or four YAML files for a simple application. They stop working well the moment you need to deploy the same application to multiple environments with different configurations, share it with someone else, or roll back a botched upgrade at 11pm. A Deployment for production needs a different image tag than staging. Ingress hostnames differ between environments. Resource limits are tuned differently. You end up copy-pasting YAML and hand-editing values, which is exactly the kind of process that leads to configuration drift and outages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hetzner Cloud for Homelab Overflow: Cost-Effective Cloud Bursting and Geo-Redundancy</title>
      <link>/posts/hetzner-cloud-homelab-overflow/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/hetzner-cloud-homelab-overflow/</guid>
      <description>&lt;p&gt;Running a homelab is great until your NAS is maxed out, your mini PC cluster is sweating under load, or you need a service to be reachable when your ISP goes down. The traditional answer is &amp;ldquo;buy more hardware,&amp;rdquo; but there&amp;rsquo;s a better option for many scenarios: overflow to a cheap, fast cloud provider.&lt;/p&gt;&#xA;&lt;p&gt;Hetzner Cloud is the standout choice for homelab operators who want genuine cloud infrastructure without the AWS/GCP/Azure pricing shock. Their CX22 (2 vCPU, 4 GB RAM) starts at €3.79/month. A CCX13 with 2 dedicated AMD vCPUs and 8 GB RAM is €12.49/month. That&amp;rsquo;s real compute, not the burstable T2/E2 nonsense that throttles you when you actually need it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Home Assistant: The Local-First Smart Home That Actually Respects Your Privacy</title>
      <link>/posts/home-assistant-home-automation/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-assistant-home-automation/</guid>
      <description>&lt;p&gt;In April 2023, Wink — a popular smart home hub that once boasted millions of users — locked customers out of their own devices unless they paid a monthly subscription fee. Devices that had worked flawlessly for years stopped responding overnight. In 2019, Lowe&amp;rsquo;s shut down the Iris smart home platform with 90 days&amp;rsquo; notice, and thousands of customers threw hardware in the bin. Google bought and killed Revolv. Samsung&amp;rsquo;s SmartThings has been through so many architecture changes that automations written two years ago no longer reliably work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Home Network Design: Wired Backbone, Wi-Fi Coverage, IoT Isolation, and Cable Management</title>
      <link>/posts/home-network-design/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/home-network-design/</guid>
      <description>&lt;p&gt;Most home networks are accidents. An ISP technician drops off a combo modem/router, you connect a few devices, and you call it done. That works until you have forty IoT devices, a Proxmox cluster doing live VM migrations, simultaneous 4K streams, and a work laptop on a video call — all competing for the same flat, unmanaged network running off hardware designed to be as cheap as possible to ship.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Homelab Hardware Guide: Mini PCs, Used Enterprise Gear, NAS Picks, and Power</title>
      <link>/posts/homelab-hardware-guide/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/homelab-hardware-guide/</guid>
      <description>&lt;p&gt;Building a homelab is not a single purchase. It is a sequence of deliberate tradeoffs between capability, cost, noise, heat, and the electricity bill that arrives every month whether you are using the hardware or not. The person setting up their first Proxmox node on a $180 mini PC and the person building out a full rack with redundant storage are solving different versions of the same problem — and both deserve hardware that fits their actual workloads.&lt;/p&gt;</description>
    </item>
    <item>
      <title>jq: The Command-Line JSON Processor You Should Already Know</title>
      <link>/posts/jq-json-processing/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/jq-json-processing/</guid>
      <description>&lt;p&gt;If you work with APIs, cloud CLIs, or any modern infrastructure tooling, you deal with JSON constantly. &lt;code&gt;jq&lt;/code&gt; is to JSON what &lt;code&gt;awk&lt;/code&gt; is to text — a purpose-built language for slicing, filtering, and transforming structured data at the command line. This guide goes from first principles to the patterns you&amp;rsquo;ll actually reach for in production.&lt;/p&gt;&#xA;&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Debian / Ubuntu&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install -y jq&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# RHEL / Rocky / Fedora&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dnf install -y jq&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# macOS&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install jq&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Alpine&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apk add jq&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Check version&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jq --version&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# jq-1.7.1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;hr&gt;&#xA;&lt;h2 id=&#34;the-mental-model&#34;&gt;The Mental Model&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; is a filter language. Every &lt;code&gt;jq&lt;/code&gt; program is a filter that takes input JSON, transforms it, and produces output JSON. You chain filters together with the pipe &lt;code&gt;|&lt;/code&gt; operator, exactly like a Unix pipeline.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes for the Homelab: K3s Setup, Workloads, and Beyond</title>
      <link>/posts/kubernetes-homelab/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-homelab/</guid>
      <description>&lt;p&gt;Kubernetes has a reputation for being the domain of hyperscale cloud teams and enterprise platform engineers. That reputation isn&amp;rsquo;t entirely wrong — a full-fat Kubernetes cluster with all the trimmings is genuinely complex. But K3s, the lightweight distribution from Rancher/SUSE, has made running Kubernetes in a homelab not just practical but genuinely pleasant. It installs in 30 seconds, runs comfortably on a single machine with 2GB of RAM, and gives you the full Kubernetes API surface without the operational overhead of managing etcd clusters and cloud-provider integrations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Desktop Environments: GNOME, KDE, XFCE, and Beyond</title>
      <link>/posts/linux-desktop-environments/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-desktop-environments/</guid>
      <description>&lt;p&gt;One of Linux&amp;rsquo;s defining characteristics is that the desktop is not baked into the operating system. The graphical environment you use — how windows look, how you launch apps, how the taskbar behaves — is a separate, swappable layer. This means you can run the same Ubuntu or Fedora base with radically different interfaces, each with its own philosophy about how a computer should work.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers the major desktop environments: what they are, how they differ, who they&amp;rsquo;re for, and how to evaluate them for yourself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Development Environments: Dev Containers, Nix Flakes, and Reproducible Setups</title>
      <link>/posts/local-development-environments/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-development-environments/</guid>
      <description>&lt;p&gt;It is 9 AM on a new developer&amp;rsquo;s first day. They clone the repo, follow the README, and immediately hit a wall: Python version mismatch, missing system library, postgres running on the wrong port, a native extension that won&amp;rsquo;t compile on their Apple Silicon Mac. By noon they have opened six Stack Overflow tabs and are quietly questioning their career choices. By end of day they have a working environment — sort of — with a collection of workarounds that only they understand, and that will cause mysterious failures for the next six months.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local LLM Deep Dive: Ollama, Quantization, and Running AI on Your Own Hardware</title>
      <link>/posts/local-llm-deep-dive/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-llm-deep-dive/</guid>
      <description>&lt;p&gt;The frontier AI services — Claude, GPT-4o, Gemini — are genuinely impressive. They are also cloud-bound, token-metered, and dependent on an internet connection. For developers and homelabbers who care about privacy, cost at scale, or just the satisfaction of owning the full stack, local LLMs have reached a point where they are genuinely useful for day-to-day coding work. This post covers everything you need to go from zero to a fully operational local AI setup: hardware selection, quantization formats, Ollama installation and configuration, model selection for coding tasks, and building a practical coding assistant that rivals cloud tools for many common tasks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Loki for Log Aggregation: Ship, Query, and Correlate Your Logs</title>
      <link>/posts/loki-log-aggregation/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/loki-log-aggregation/</guid>
      <description>&lt;p&gt;Your Prometheus dashboards are clean. CPU, memory, disk, request rates — all graphed and alerting. Then something breaks at 2am and the metrics tell you &lt;em&gt;that&lt;/em&gt; something happened, but not &lt;em&gt;why&lt;/em&gt;. The error rate spiked. Memory climbed. A container restarted three times. What actually went wrong? The answer is in the logs — and if your logs are scattered across a dozen hosts with no central place to query them, you are SSH-ing into boxes and grepping files while the incident is still open.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mentoring Junior Engineers: What Actually Helps vs. What Feels Like Helping</title>
      <link>/posts/mentoring-junior-engineers/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/mentoring-junior-engineers/</guid>
      <description>&lt;p&gt;Most engineers who mentor juniors are doing it without training, without a framework, and often without fully understanding what they&amp;rsquo;re actually trying to accomplish. They default to what was done to them — a mix of code review comments, &amp;ldquo;let me show you,&amp;rdquo; and occasionally overwhelming a new hire with the entire codebase at once.&lt;/p&gt;&#xA;&lt;p&gt;Some of that works. A lot of it doesn&amp;rsquo;t. And the gap between &amp;ldquo;feels like helping&amp;rdquo; and &amp;ldquo;actually helps&amp;rdquo; is worth understanding, because bad mentoring doesn&amp;rsquo;t just waste time — it can actively slow someone down, erode their confidence, or teach them exactly the wrong lessons.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Network Segmentation with VLANs: Isolating Traffic on Your Homelab and Beyond</title>
      <link>/posts/network-segmentation-vlans/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/network-segmentation-vlans/</guid>
      <description>&lt;p&gt;A flat network — where every device can talk to every other device — is fine when you have three things plugged in. Once you add smart TVs, IoT sensors, work laptops, servers, a NAS, and guest devices, a flat network becomes a liability. If any device is compromised, an attacker has unrestricted access to everything else. VLANs are the solution: a way to logically divide one physical network into multiple isolated segments without buying extra switches.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nextcloud: Your Self-Hosted Google Workspace Replacement</title>
      <link>/posts/nextcloud-google-workspace-replacement/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nextcloud-google-workspace-replacement/</guid>
      <description>&lt;p&gt;Every time you open Google Drive, Google&amp;rsquo;s crawlers have already read what&amp;rsquo;s in it. Every calendar event feeds a behavioral profile. Every document you collaborate on in Google Docs is processed, indexed, and used to serve ads and train models. You agreed to this in the Terms of Service — you just probably didn&amp;rsquo;t think about it much.&lt;/p&gt;&#xA;&lt;p&gt;For individual users the price is your data. For teams the price is also money: Google Workspace Business Starter is $6/user/month, Business Standard is $12/user/month, and it scales from there. A ten-person team on Business Standard is $1,440/year for a suite you don&amp;rsquo;t control, running on hardware you&amp;rsquo;ve never seen, in a jurisdiction that may not be your own.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NFS Filers in Azure: A Complete Management Guide</title>
      <link>/posts/nfs-filers-azure/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/nfs-filers-azure/</guid>
      <description>&lt;p&gt;Network File System (NFS) in Azure comes in two main flavors: &lt;strong&gt;Azure NetApp Files (ANF)&lt;/strong&gt;, a fully managed enterprise NAS service built on NetApp ONTAP, and &lt;strong&gt;Azure Files NFS&lt;/strong&gt;, a simpler managed SMB/NFS file share. This guide focuses primarily on Azure NetApp Files because it is the right choice for most production NFS workloads — higher throughput, genuine per-user quotas, snapshot management, and significantly more operational control. Azure Files NFS is covered where it fits.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenAPI and Swagger: Designing and Documenting APIs Contract-First</title>
      <link>/posts/openapi-swagger/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/openapi-swagger/</guid>
      <description>&lt;p&gt;Every API starts the same way: someone opens a blank file (or a blank Express router) and starts writing endpoints. Six months later, the API is a reflection of implementation details no one consciously chose — query parameters named after database column names, response shapes that evolved from whatever was convenient to return, inconsistent error formats across endpoints, and documentation that&amp;rsquo;s already out of date.&lt;/p&gt;&#xA;&lt;p&gt;Contract-first API design is the discipline of defining the API &lt;em&gt;before&lt;/em&gt; writing implementation code — treating the API spec as the primary artifact, not an afterthought. The OpenAPI Specification is the industry standard for doing exactly that.&lt;/p&gt;</description>
    </item>
    <item>
      <title>pfSense and OPNsense: The Complete Home Lab Firewall Guide</title>
      <link>/posts/pfsense-opnsense-setup/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/pfsense-opnsense-setup/</guid>
      <description>&lt;p&gt;Your ISP-supplied router is a security liability masquerading as a convenience. It runs firmware that gets updated once every few years (if ever), exposes a web interface that&amp;rsquo;s been the subject of countless CVEs, and gives you essentially no visibility into what&amp;rsquo;s actually happening on your network. The moment you start running servers, VMs, or anything beyond casual browsing, you need a real firewall.&lt;/p&gt;&#xA;&lt;p&gt;pfSense and OPNsense are BSD-based open-source firewall distributions that turn commodity x86 hardware into enterprise-grade network appliances. They support everything from basic NAT to multi-WAN failover, IDS/IPS, VPN concentrators, VLAN trunking, traffic shaping, and high availability clustering — all from a polished web GUI backed by battle-tested FreeBSD networking code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Podman vs Docker: Rootless Containers, Pods, and the Case for Switching</title>
      <link>/posts/podman-vs-docker/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/podman-vs-docker/</guid>
      <description>&lt;p&gt;Docker democratized containers. It gave developers a simple, consistent way to package and run software that has fundamentally changed how we build and deploy applications. If you&amp;rsquo;ve been running containers for any length of time, Docker is almost certainly where you started.&lt;/p&gt;&#xA;&lt;p&gt;But Docker carries architectural baggage that matters more the longer you operate in production: a persistent root daemon, a socket that is effectively a root shell, rootless mode bolted on as an afterthought, and no native concept of container grouping. These aren&amp;rsquo;t dealbreakers for many use cases, but they&amp;rsquo;re real constraints — particularly if you care about security, systemd integration, or preparing workloads for Kubernetes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Profiling Applications: Finding Bottlenecks in Go, Python, and Node.js</title>
      <link>/posts/profiling-applications/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/profiling-applications/</guid>
      <description>&lt;p&gt;Your application is slow. Requests that should take 50ms are taking 800ms. Memory usage is creeping up every hour and you&amp;rsquo;re not sure why. You&amp;rsquo;ve already tried the obvious things — added an index here, reduced a payload there — but the problem persists.&lt;/p&gt;&#xA;&lt;p&gt;The instinct is to scan the code and optimize what &lt;em&gt;looks&lt;/em&gt; expensive. This almost always fails. The things that look slow often aren&amp;rsquo;t, and the actual bottleneck is frequently somewhere mundane: a string format call inside a tight loop, a missing cache, a goroutine that never exits, a JSON parse that happens on every request.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Proxmox VE: The Ultimate Homelab Hypervisor</title>
      <link>/posts/proxmox-ve-setup/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/proxmox-ve-setup/</guid>
      <description>&lt;p&gt;At some point every homelabber reaches the same inflection point: three physical machines running three workloads, none of them fully utilized, each one drawing power around the clock. The natural answer is consolidation — run everything on one or two powerful hosts, isolated in virtual machines and containers. For that job, Proxmox Virtual Environment has become the undisputed homelab standard, and for good reason.&lt;/p&gt;&#xA;&lt;p&gt;Proxmox VE is a free, open-source Type-1 hypervisor built on a foundation of Debian Linux, KVM (Kernel-based Virtual Machine), and LXC (Linux Containers). It wraps those battle-tested technologies in a polished web UI, adds built-in support for ZFS, Ceph, enterprise clustering, live migration, and high availability, and ships it all under the AGPL license — free to use, forever, no license key required. The enterprise support subscription is optional and brings nothing you actually need for a homelab.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RAG from Scratch: Building a Retrieval-Augmented Chatbot Over Your Own Documents</title>
      <link>/posts/rag-from-scratch/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/rag-from-scratch/</guid>
      <description>&lt;p&gt;Every LLM you interact with has a hard stop in time. It was trained on data up to a certain date, and it knows nothing about anything that happened after. More importantly, it knows nothing about &lt;em&gt;your&lt;/em&gt; data — your internal documentation, your architecture decision records, your private knowledge base, your team&amp;rsquo;s runbooks. When you ask a general-purpose model about your own codebase or your company&amp;rsquo;s systems, it can only guess.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running a Local Knowledge Base: Obsidian, Logseq, and AI-Powered Search Over Your Notes</title>
      <link>/posts/local-knowledge-base/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-knowledge-base/</guid>
      <description>&lt;p&gt;Most knowledge management systems fail for the same reason: they&amp;rsquo;re optimized for capturing information and terrible at retrieving it. You spend years faithfully taking notes, building a second brain, and then when you actually need something you either can&amp;rsquo;t find it or don&amp;rsquo;t remember it exists.&lt;/p&gt;&#xA;&lt;p&gt;The promise of AI-powered search is that it flips this. Instead of trying to remember which folder you filed something in three years ago, you ask &amp;ldquo;what do I know about rate limiting strategies?&amp;rdquo; and get a synthesized answer drawn from everything you&amp;rsquo;ve ever written.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Self-Hosting Your Email: Postfix, Dovecot, Stalwart, and the Deliverability Gauntlet</title>
      <link>/posts/self-hosting-email/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/self-hosting-email/</guid>
      <description>&lt;p&gt;Running your own mail server is the final frontier of self-hosting. You can containerize every other workload, own your DNS, proxy everything through Traefik, and still depend on Google or Microsoft for the service that arguably matters most. Email is the identity layer of the internet — it&amp;rsquo;s how you reset passwords, receive invoices, and communicate with people who aren&amp;rsquo;t on your preferred platform. Owning that layer completely is a compelling idea.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Shell Scripting for Sysadmins: Automating the Work That Never Ends</title>
      <link>/posts/shell-scripting-for-sysadmins/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/shell-scripting-for-sysadmins/</guid>
      <description>&lt;p&gt;System administration is full of repetitive tasks: creating users, checking disk space, rotating logs, auditing who&amp;rsquo;s logged in, restarting misbehaving services. Each one is simple in isolation. Done manually, day after day, they consume hours and introduce human error. This guide focuses on the practical side — real scripts you can adapt and use, built around the tasks that fill a sysadmin&amp;rsquo;s week.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;the-sysadmin-script-starter-template&#34;&gt;The Sysadmin Script Starter Template&lt;/h2&gt;&#xA;&lt;p&gt;Every script in this guide uses this foundation:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Side Projects That Ship: Scoping, Finishing, and Launching Small Tools</title>
      <link>/posts/side-projects-that-ship/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/side-projects-that-ship/</guid>
      <description>&lt;p&gt;Every developer has a graveyard. A &lt;code&gt;~/projects&lt;/code&gt; folder full of directories that represent the first three excited weekends of some idea, then silence. A half-built CLI tool. A database schema for the app that was going to replace Notion. A scraper that worked once. A game that got as far as a moving sprite.&lt;/p&gt;&#xA;&lt;p&gt;This is universal and it&amp;rsquo;s not a character flaw. Side projects have a natural attractor state: stuck at 80%, not bad enough to delete, not finished enough to use. The graveyard grows.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SSH Hardening: Locking Down the Door Every Server Has Open</title>
      <link>/posts/ssh-hardening/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ssh-hardening/</guid>
      <description>&lt;p&gt;SSH is the front door to every Linux server. It&amp;rsquo;s also one of the most attacked services on the internet — automated scanners probe port 22 constantly, trying default credentials and known exploits. Default SSH configuration is functional but not secure. This guide covers what to lock down, what to enable, and how to build an SSH setup that&amp;rsquo;s both convenient for legitimate users and extremely hostile to everyone else.&lt;/p&gt;</description>
    </item>
    <item>
      <title>strace and ltrace: Debugging Processes at the System Call Level</title>
      <link>/posts/strace-ltrace-deep-dive/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/strace-ltrace-deep-dive/</guid>
      <description>&lt;p&gt;When a program behaves unexpectedly and you can&amp;rsquo;t attach a debugger, or you&amp;rsquo;re working with a binary you don&amp;rsquo;t have source for, &lt;code&gt;strace&lt;/code&gt; and &lt;code&gt;ltrace&lt;/code&gt; cut through the mystery. They show you exactly what a process is asking the kernel to do — every file it opens, every network connection it makes, every signal it sends. This guide covers both tools from practical first use through advanced production debugging techniques.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Terraform for the Homelab: Manage Local and Cloud Resources with One Workflow</title>
      <link>/posts/terraform-homelab/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/terraform-homelab/</guid>
      <description>&lt;p&gt;At some point every homelabber hits the same wall. You&amp;rsquo;ve got Proxmox running a dozen VMs, a couple of cloud VPS instances for services that need a public IP, and a Cloudflare account managing DNS. You know what every resource does because you built it — but you clicked through UIs to create all of it, and the &amp;ldquo;documentation&amp;rdquo; lives entirely in your head. Disaster-recovery planning amounts to hoping you remember the steps if something goes wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Art of the Postmortem: Blameless Incident Reviews That Actually Change Things</title>
      <link>/posts/art-of-the-postmortem/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/art-of-the-postmortem/</guid>
      <description>&lt;p&gt;You&amp;rsquo;ve read this document before. The date is different, the service name is different, but the structure is the same: a vague timeline, a root cause section that reads &amp;ldquo;engineer deployed broken config,&amp;rdquo; and a list of action items that starts with &amp;ldquo;add more monitoring.&amp;rdquo; It was written within 48 hours of the incident, filed in a shared drive, and never opened again.&lt;/p&gt;&#xA;&lt;p&gt;Six months later, the same service goes down in almost the same way.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Linux Boot Process: From Power Button to Login Prompt</title>
      <link>/posts/linux-boot-process/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-boot-process/</guid>
      <description>&lt;p&gt;Most Linux users interact with their system only after it&amp;rsquo;s already running. But understanding the boot sequence pays real dividends: you can rescue a system that won&amp;rsquo;t boot, diagnose startup failures, tune boot performance, and reason confidently about what&amp;rsquo;s happening when something goes wrong before the login prompt appears.&lt;/p&gt;&#xA;&lt;p&gt;This guide walks every stage of the modern Linux boot process, from firmware to the point where you can log in.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Prometheus &#43; Grafana Stack: Metrics, Alerting, and Dashboards</title>
      <link>/posts/prometheus-grafana-stack/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/prometheus-grafana-stack/</guid>
      <description>&lt;p&gt;Something is wrong with your server at 3am. Response times climbed for 45 minutes before the on-call page fired. Now you&amp;rsquo;re staring at a terminal and asking yourself: was it CPU? Memory pressure? A disk filling up? A container that kept OOM-crashing and restarting? Did it start before or after that deploy?&lt;/p&gt;&#xA;&lt;p&gt;Without metrics, you are guessing. With Prometheus and Grafana, you scroll back in time, pull up the exact 45-minute window, and the answer is sitting right there in a graph — CPU saturation on one core, caused by a container that had no resource limits and decided to consume everything it could reach.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Self-Hosted Media Server Stack: Jellyfin, the *arr Apps, and Full Automation</title>
      <link>/posts/media-server-stack/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/media-server-stack/</guid>
      <description>&lt;p&gt;There is a specific kind of frustration that comes from opening Netflix to watch a film you remember being there, only to find it&amp;rsquo;s gone. Or opening HBO Max — sorry, Max — to finish a series, then discovering the app has been rebranded, your watchlist has vanished, and the show was quietly removed because of a tax write-down. Or splitting a streaming bill seven ways across family members and still not having access to everything you want to watch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Uptime Kuma: Self-Hosted Status Pages and Alerting Done Right</title>
      <link>/posts/uptime-kuma/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/uptime-kuma/</guid>
      <description>&lt;p&gt;Your Gitea instance went down at 11pm on a Tuesday. Nobody noticed until the developer trying to push code at 9am Wednesday morning hit a connection refused error. Eight hours of undetected downtime, and the fix was a simple container restart.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s the problem Uptime Kuma solves. It sits inside your network, pings every service you run on a configurable interval, and fires a notification the moment something stops responding — to Telegram, Slack, Discord, email, Gotify, ntfy, PagerDuty, or any of 90+ other destinations. It also generates a status page you can share with users or teammates, complete with 90-day uptime history and incident announcements.&lt;/p&gt;</description>
    </item>
    <item>
      <title>vim/neovim for DevOps: Your Terminal Editor, Supercharged</title>
      <link>/posts/vim-neovim-for-devops/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vim-neovim-for-devops/</guid>
      <description>&lt;p&gt;Nearly every server you&amp;rsquo;ll ever SSH into has &lt;code&gt;vi&lt;/code&gt; or &lt;code&gt;vim&lt;/code&gt;. No GUI, no VS Code tunnel, no escape hatch — just you and the terminal. That&amp;rsquo;s the survival argument for learning vim. But there&amp;rsquo;s a stronger one: once it clicks, vim is genuinely the fastest way to edit text. This guide gets you from &amp;ldquo;how do I exit?&amp;rdquo; to &amp;ldquo;I can&amp;rsquo;t imagine working without this.&amp;rdquo;&lt;/p&gt;&#xA;&lt;h2 id=&#34;vim-vs-neovim&#34;&gt;vim vs neovim&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;vim&lt;/strong&gt; is the classic, ships everywhere, rock-solid. &lt;strong&gt;neovim&lt;/strong&gt; is a modern fork with a better plugin API (Lua instead of Vimscript), built-in LSP support, and a more active plugin ecosystem. The core editing model is identical — everything in this guide applies to both.&lt;/p&gt;</description>
    </item>
    <item>
      <title>WireGuard VPN: Fast, Modern, and Actually Understandable</title>
      <link>/posts/wireguard-vpn/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/wireguard-vpn/</guid>
      <description>&lt;p&gt;WireGuard is what VPN software should have always been. The reference implementation is around 4,000 lines of code — OpenVPN is over 100,000. It lives in the Linux kernel. It connects in under 100 milliseconds. Its cryptography is modern and non-negotiable: no cipher suites to misconfigure, no weak defaults to stumble into. If you&amp;rsquo;ve avoided VPNs because they were complicated, WireGuard is the exception.&lt;/p&gt;&#xA;&lt;p&gt;This guide covers everything from the first key pair to a production multi-peer deployment with split tunneling, road warrior clients, and a site-to-site tunnel.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing Good READMEs: Documentation That Developers Actually Read</title>
      <link>/posts/writing-good-readmes/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/writing-good-readmes/</guid>
      <description>&lt;p&gt;The README is the front door of your project. Before anyone clones your repo, reads your code, or files an issue, they read your README. Most of them decide within 30 seconds whether your project is worth their time.&lt;/p&gt;&#xA;&lt;p&gt;Most READMEs fail that test.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-readmes-matter-and-why-most-are-bad&#34;&gt;Why READMEs Matter (and Why Most Are Bad)&lt;/h2&gt;&#xA;&lt;p&gt;There&amp;rsquo;s a strange irony in software development: the same engineer who would never write a function without thinking carefully about its interface will write a README as an afterthought — a few bullet points dashed off after the &amp;ldquo;real work&amp;rdquo; is done.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Zero Trust Networking: Principles and Practical Tools</title>
      <link>/posts/zero-trust-networking/</link>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/zero-trust-networking/</guid>
      <description>&lt;p&gt;The old security model had a simple premise: build a strong perimeter, and trust everything inside it. A thick firewall at the network edge, a VPN to get through that firewall, and then — once you were in — broad access to internal resources. The castle had a moat. You either crossed the moat or you didn&amp;rsquo;t.&lt;/p&gt;&#xA;&lt;p&gt;That model is dead. It was killed by cloud computing, remote work, SaaS applications, mobile devices, and the uncomfortable reality that attackers who breach the perimeter — or malicious insiders who were always inside it — face almost no resistance once they&amp;rsquo;re in. The 2020 SolarWinds breach moved laterally across networks for months before detection. The 2021 Colonial Pipeline ransomware spread from a compromised VPN account. In both cases, once past the moat, the castle interior was wide open.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Microsoft Azure as a Personal VPS: The Complete Guide to Pricing, Setup, and Cost Optimization</title>
      <link>/posts/azure-vps-guide/</link>
      <pubDate>Fri, 13 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/azure-vps-guide/</guid>
      <description>&lt;p&gt;Microsoft Azure is one of the world&amp;rsquo;s largest cloud platforms, second only to AWS in market share. It&amp;rsquo;s typically thought of as enterprise territory — massive corporations, compliance-heavy deployments, and six-figure contracts. But Azure has a surprisingly compelling story for individual developers, homelab enthusiasts, and small-project runners who want reliable global infrastructure without managing physical hardware.&lt;/p&gt;&#xA;&lt;p&gt;This guide is your deep dive into Azure as a personal VPS: understanding the VM landscape, decoding the pricing models, getting a server locked down and running from scratch, and — crucially — mastering the strategies that can slash your monthly bill from &amp;ldquo;ouch&amp;rdquo; to &amp;ldquo;fine, actually.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Monitoring and Observability: From the Golden Signals to a Complete Self-Hosted Stack</title>
      <link>/posts/monitoring-and-observability/</link>
      <pubDate>Fri, 13 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/monitoring-and-observability/</guid>
      <description>&lt;p&gt;Monitoring isn&amp;rsquo;t about collecting metrics. It&amp;rsquo;s about understanding your systems well enough to know when something is wrong and why. You&amp;rsquo;ve set up your VPS, configured your Docker containers, reverse proxy, and TLS. Services are running. Then one day something breaks — and you have no idea when it started, what caused it, or whether it&amp;rsquo;s actually fixed. You&amp;rsquo;re flying blind.&lt;/p&gt;&#xA;&lt;p&gt;This guide does two things. First it covers &lt;em&gt;what to measure and why&lt;/em&gt;: the frameworks (RED, USE, the Four Golden Signals), percentiles, SLOs, and alerting that doesn&amp;rsquo;t burn you out. Then it builds a complete, self-hosted observability stack from scratch using the open-source gold standard — &lt;strong&gt;Prometheus&lt;/strong&gt; for metrics, &lt;strong&gt;Loki&lt;/strong&gt; for logs, &lt;strong&gt;Grafana&lt;/strong&gt; for visualization, and &lt;strong&gt;Alertmanager&lt;/strong&gt; for notifications. Everything runs in Docker, works equally well on a single VPS or a homelab cluster, and costs nothing beyond your server time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenClaw: The Complete Guide to Self-Hosted AI Agents</title>
      <link>/posts/openclaw-self-hosted-ai-agents/</link>
      <pubDate>Fri, 13 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/openclaw-self-hosted-ai-agents/</guid>
      <description>&lt;p&gt;In the autumn of 2025, an Austrian developer named Peter Steinberger built a side project to scratch his own itch: a bot that let an AI actually &lt;em&gt;do things&lt;/em&gt; on his computer rather than just answer questions. He open-sourced it in November 2025 under the name &lt;strong&gt;Clawdbot&lt;/strong&gt;, and for a couple of months it was a niche curiosity. Then, in late January 2026, it went supernova — over 100,000 GitHub stars in 48 hours, 190,000 within two weeks. Anthropic&amp;rsquo;s legal team sent a trademark letter over the &amp;ldquo;Clawd&amp;rdquo; name, the community scrambled through an interim rename to &lt;strong&gt;Moltbot&lt;/strong&gt;, and on January 30, 2026 the project landed on its final name: &lt;strong&gt;OpenClaw&lt;/strong&gt;. By March 2026 it had crossed a quarter-million stars, a thousand contributors, and an estimated 300,000–400,000 active users.&lt;/p&gt;</description>
    </item>
    <item>
      <title>PRD: FreshDeal — A Real-Time Food Discount Discovery Platform</title>
      <link>/posts/food-deals-platform-prd/</link>
      <pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/food-deals-platform-prd/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Document type:&lt;/strong&gt; Product Requirements Document (PRD)&#xA;&lt;strong&gt;Status:&lt;/strong&gt; Draft v1.0 — Pre-development&#xA;&lt;strong&gt;Audience:&lt;/strong&gt; Engineering, design, and stakeholders&#xA;&lt;strong&gt;Last updated:&lt;/strong&gt; March 2026&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;vision-statement&#34;&gt;Vision Statement&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;FreshDeal&lt;/strong&gt; is a web platform that aggregates restaurant and food service discounts in real time, surfaces the best deals based on the user&amp;rsquo;s location and preferences, and automatically removes any deal that has expired — so users never see a dead link, a coupon that won&amp;rsquo;t scan, or a &amp;ldquo;this offer ended last week&amp;rdquo; moment. The promise to the user is simple: every deal on FreshDeal is active right now.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Complete Guide to Stretching: Science, Technique, and Building Lasting Flexibility</title>
      <link>/posts/complete-guide-to-stretching/</link>
      <pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/complete-guide-to-stretching/</guid>
      <description>&lt;p&gt;Most people&amp;rsquo;s stretching routine consists of a few halfhearted toe touches before a run, maybe a hamstring stretch while they&amp;rsquo;re thinking about something else, and a vague intention to do more of it someday. That&amp;rsquo;s a shame, because a well-designed stretching practice is one of the most accessible, lowest-equipment-cost investments you can make in long-term physical health — and the gap between what most people do and what the research actually supports is enormous.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Traefik: The Complete Guide to the Cloud-Native Reverse Proxy</title>
      <link>/posts/traefik-complete-guide/</link>
      <pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/traefik-complete-guide/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve run more than a handful of services on a single server or home lab, you know the pain of the traditional reverse proxy workflow: edit a config file, add a server block, reload nginx, add a certificate renewal entry to cron, update your mental map of which port serves what. Every new service means another round of manual changes.&lt;/p&gt;&#xA;&lt;p&gt;Traefik turns this model upside down. Rather than you telling the proxy about your services, Traefik watches your infrastructure — Docker socket, Kubernetes API, Consul, Nomad, or a directory of YAML files — and configures itself automatically as services appear, scale, and disappear. Add a new Docker container with the right labels and Traefik picks it up, assigns it a route, and procures a TLS certificate — all without touching a config file. Remove the container and the route vanishes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bitcoin and Cryptocurrency Explained: How It Works, Benefits, Risks, and Investing Strategies</title>
      <link>/posts/bitcoin-and-cryptocurrency-explained/</link>
      <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/bitcoin-and-cryptocurrency-explained/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This post is educational only. Nothing here constitutes financial or investment advice. Cryptocurrency investing involves substantial risk, including the potential total loss of invested capital. Always conduct your own research and consult a licensed financial advisor before making investment decisions.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Bitcoin was proposed in October 2008 by a pseudonymous person or group called Satoshi Nakamoto in a nine-page white paper titled &amp;ldquo;Bitcoin: A Peer-to-Peer Electronic Cash System.&amp;rdquo; The timing was not accidental. Lehman Brothers had collapsed five weeks earlier, triggering the worst financial crisis since the Great Depression and revealing how fragile the trust-based architecture of the global banking system really was.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Start a New Job the Right Way: A Practical Playbook</title>
      <link>/posts/starting-a-new-job/</link>
      <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/starting-a-new-job/</guid>
      <description>&lt;p&gt;The first ninety days of a job determine more about your trajectory at a company than the next two years combined. Not because first impressions are unfair, but because the patterns you establish — how you communicate, how you prioritize, how you build trust, what you choose to work on — become the baseline everyone compares everything else to.&lt;/p&gt;&#xA;&lt;p&gt;Most people start a new job the same way: enthusiastic, slightly overwhelmed, trying to absorb everything at once, working long hours to prove themselves, and making a handful of quiet mistakes they don&amp;rsquo;t realize are mistakes until much later. This guide is an attempt to interrupt that pattern with something more deliberate.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Vibecoder&#39;s Home Lab: Running AI Agents Across Multiple Machines</title>
      <link>/posts/homelab-ai-agents/</link>
      <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/homelab-ai-agents/</guid>
      <description>&lt;p&gt;Vibecoding — the practice of directing AI agents to write, refactor, test, and ship code while you focus on architecture, intent, and review — has a hardware and infrastructure problem. The tools are evolving fast. But the default setup most people use — a single laptop, one terminal, one AI session at a time — leaves enormous throughput on the table.&lt;/p&gt;&#xA;&lt;p&gt;An AI coding agent working on a non-trivial task takes five to twenty minutes. During that time, you are either watching it or doing something unrelated. A home lab built for vibecoding multiplies your effective output by running multiple agents in parallel across isolated environments, with a network that connects everything seamlessly, a shell configured to make orchestration fast, and storage and compute provisioned to handle model inference locally when you want privacy or cost control.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Complete VPS Setup Guide: Security, Performance, and Quality of Life</title>
      <link>/posts/vps-setup-best-practices/</link>
      <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/vps-setup-best-practices/</guid>
      <description>&lt;p&gt;A freshly provisioned VPS is a blank canvas: a full operating system with root access and a public IP address. That freedom is exhilarating and dangerous in equal measure. Within minutes of boot, automated scanners will find your server and begin probing every port. Without intervention, a default Ubuntu or Debian install will have SSH open to the entire internet, root login enabled, and password authentication accepting guesses from anywhere.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Developer&#39;s Career Playbook: Changing Jobs, Remote Work, and Negotiating Salary</title>
      <link>/posts/career-job-changes-remote-work-salary/</link>
      <pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate>
      <guid>/posts/career-job-changes-remote-work-salary/</guid>
      <description>&lt;p&gt;Most career advice is written by people who have never sat across from a hiring manager and tried to negotiate a $30,000 gap, or by HR professionals whose interests are not quite the same as yours. This guide tries to be different: direct, specific, occasionally uncomfortable, and genuinely useful.&lt;/p&gt;&#xA;&lt;p&gt;Three decisions shape a tech career more than almost any other. When to leave a job. Whether to work remotely. How to negotiate your salary. They intersect constantly — you negotiate better when you have options, remote work changes your leverage, and knowing when to leave is inseparable from knowing your market value. This post covers all three, in depth.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local LLM Inference for Coding: The Complete 2025/2026 Guide</title>
      <link>/posts/local-llm-coding-guide/</link>
      <pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate>
      <guid>/posts/local-llm-coding-guide/</guid>
      <description>&lt;div class=&#34;affiliate-notice&#34;&gt;&#xA;  &lt;strong&gt;Disclosure:&lt;/strong&gt; This post contains affiliate links. If you make a purchase through these links, we may earn a small commission at no extra cost to you. This helps support LunarOps and allows us to continue creating quality content.&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;Running AI coding assistants locally has shifted from a hobbyist experiment to a genuinely competitive alternative to cloud-based tools. In 2025, models like Qwen2.5-Coder-32B match GPT-4o on HumanEval benchmarks, and the tooling — Ollama, LM Studio, llama.cpp — has matured to the point where setup takes minutes rather than days. This guide covers everything from model selection and hardware requirements to full editor integration with Continue.dev and Aider.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SLURM: The HPC Job Scheduler — From Basics to Advanced Administration</title>
      <link>/posts/slurm-job-scheduler/</link>
      <pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate>
      <guid>/posts/slurm-job-scheduler/</guid>
      <description>&lt;p&gt;If you work anywhere near high-performance computing, scientific computing, or large-scale ML infrastructure, you&amp;rsquo;ve almost certainly encountered &lt;strong&gt;SLURM&lt;/strong&gt;. It runs on over 65% of the TOP500 supercomputers and is the de facto standard for cluster workload management. This post covers everything from its origins to advanced administrative tuning and job efficiency analysis.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;history&#34;&gt;History&lt;/h2&gt;&#xA;&lt;h3 id=&#34;origins-at-llnl-20012002&#34;&gt;Origins at LLNL (2001–2002)&lt;/h3&gt;&#xA;&lt;p&gt;SLURM — originally an acronym for &lt;strong&gt;Simple Linux Utility for Resource Management&lt;/strong&gt; — was born out of necessity at &lt;strong&gt;Lawrence Livermore National Laboratory (LLNL)&lt;/strong&gt; in 2001. LLNL was transitioning from proprietary supercomputer systems to commodity Linux clusters and needed an open, scalable workload manager to replace the proprietary schedulers that came with vendor hardware.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker Best Practices for Local Development</title>
      <link>/posts/docker-best-practices/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/docker-best-practices/</guid>
      <description>&lt;p&gt;Docker has become essential for local development, but there&amp;rsquo;s a difference between &amp;ldquo;it works&amp;rdquo; and &amp;ldquo;it works well.&amp;rdquo; Here are practices I&amp;rsquo;ve learned that make Docker development smoother.&lt;/p&gt;&#xA;&lt;h2 id=&#34;use-multi-stage-builds&#34;&gt;Use Multi-Stage Builds&lt;/h2&gt;&#xA;&lt;p&gt;Multi-stage builds keep your final images small by separating build dependencies from runtime.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Build stage&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;node:20-alpine&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;builder&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WORKDIR&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;/app&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;COPY&lt;/span&gt; package*.json ./&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;RUN&lt;/span&gt; npm ci&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;COPY&lt;/span&gt; . .&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;RUN&lt;/span&gt; npm run build&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Production stage&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;node:20-alpine&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WORKDIR&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;/app&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;COPY&lt;/span&gt; --from&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;builder /app/dist ./dist&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;COPY&lt;/span&gt; --from&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;builder /app/node_modules ./node_modules&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CMD&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;node&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dist/index.js&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The build stage has all your dev dependencies; the final image only has what&amp;rsquo;s needed to run.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Essential Unix Commands Every Developer Should Know</title>
      <link>/posts/essential-unix-commands/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/essential-unix-commands/</guid>
      <description>&lt;p&gt;Whether you&amp;rsquo;re navigating servers, managing files, or debugging applications, Unix commands are essential tools. Here&amp;rsquo;s a curated list of commands that will make you more productive.&lt;/p&gt;&#xA;&lt;h2 id=&#34;file-navigation&#34;&gt;File Navigation&lt;/h2&gt;&#xA;&lt;h3 id=&#34;pwd---print-working-directory&#34;&gt;pwd - Print Working Directory&lt;/h3&gt;&#xA;&lt;p&gt;Always know where you are:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pwd&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# /home/user/projects&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;cd---change-directory&#34;&gt;cd - Change Directory&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /var/log          &lt;span style=&#34;color:#75715e&#34;&gt;# Absolute path&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd ../               &lt;span style=&#34;color:#75715e&#34;&gt;# Parent directory&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd -                 &lt;span style=&#34;color:#75715e&#34;&gt;# Previous directory&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd ~                 &lt;span style=&#34;color:#75715e&#34;&gt;# Home directory&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;ls---list-directory-contents&#34;&gt;ls - List Directory Contents&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls                   &lt;span style=&#34;color:#75715e&#34;&gt;# Basic listing&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls -la               &lt;span style=&#34;color:#75715e&#34;&gt;# Long format, including hidden files&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls -lh               &lt;span style=&#34;color:#75715e&#34;&gt;# Human-readable file sizes&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls -lt               &lt;span style=&#34;color:#75715e&#34;&gt;# Sort by modification time&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls -lS               &lt;span style=&#34;color:#75715e&#34;&gt;# Sort by size&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;file-operations&#34;&gt;File Operations&lt;/h2&gt;&#xA;&lt;h3 id=&#34;cp---copy-files&#34;&gt;cp - Copy Files&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp file.txt backup.txt           &lt;span style=&#34;color:#75715e&#34;&gt;# Copy file&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp -r directory/ backup/         &lt;span style=&#34;color:#75715e&#34;&gt;# Copy directory recursively&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp -p file.txt backup.txt        &lt;span style=&#34;color:#75715e&#34;&gt;# Preserve permissions and timestamps&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;mv---move-or-rename&#34;&gt;mv - Move or Rename&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv old.txt new.txt               &lt;span style=&#34;color:#75715e&#34;&gt;# Rename&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv file.txt /other/directory/    &lt;span style=&#34;color:#75715e&#34;&gt;# Move&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv *.log /var/log/               &lt;span style=&#34;color:#75715e&#34;&gt;# Move multiple files&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;rm---remove-files&#34;&gt;rm - Remove Files&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rm file.txt                      &lt;span style=&#34;color:#75715e&#34;&gt;# Remove file&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rm -r directory/                 &lt;span style=&#34;color:#75715e&#34;&gt;# Remove directory recursively&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rm -i file.txt                   &lt;span style=&#34;color:#75715e&#34;&gt;# Interactive (confirm before delete)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: &lt;code&gt;rm -rf&lt;/code&gt; is dangerous. Always double-check your path.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Securing Your Home Lab</title>
      <link>/posts/securing-home-lab/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/securing-home-lab/</guid>
      <description>&lt;p&gt;Running a home lab is a great way to learn and self-host services. But exposing services—even on your local network—carries risk. Here&amp;rsquo;s how to secure your setup without going overboard.&lt;/p&gt;&#xA;&lt;h2 id=&#34;network-segmentation&#34;&gt;Network Segmentation&lt;/h2&gt;&#xA;&lt;p&gt;Don&amp;rsquo;t put everything on one network. Separate your devices by trust level.&lt;/p&gt;&#xA;&lt;h3 id=&#34;vlan-setup&#34;&gt;VLAN Setup&lt;/h3&gt;&#xA;&lt;p&gt;A typical home lab might have:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;VLAN&lt;/th&gt;&#xA;          &lt;th&gt;Name&lt;/th&gt;&#xA;          &lt;th&gt;Purpose&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;1&lt;/td&gt;&#xA;          &lt;td&gt;Management&lt;/td&gt;&#xA;          &lt;td&gt;Router, switches, access points&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;10&lt;/td&gt;&#xA;          &lt;td&gt;Trusted&lt;/td&gt;&#xA;          &lt;td&gt;Personal devices, workstations&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;20&lt;/td&gt;&#xA;          &lt;td&gt;Lab&lt;/td&gt;&#xA;          &lt;td&gt;Servers, experimental services&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;30&lt;/td&gt;&#xA;          &lt;td&gt;IoT&lt;/td&gt;&#xA;          &lt;td&gt;Smart devices, cameras&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;40&lt;/td&gt;&#xA;          &lt;td&gt;Guest&lt;/td&gt;&#xA;          &lt;td&gt;Visitor devices&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;why-this-matters&#34;&gt;Why This Matters&lt;/h3&gt;&#xA;&lt;p&gt;If your IoT camera gets compromised (they often do), attackers can&amp;rsquo;t pivot to your servers or personal machines. Each VLAN is an island.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Self-Hosting vs Cloud: A Cost Analysis</title>
      <link>/posts/self-hosting-vs-cloud/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/self-hosting-vs-cloud/</guid>
      <description>&lt;p&gt;The cloud vs self-hosting debate often lacks concrete numbers. Let&amp;rsquo;s fix that with a real cost comparison across different scenarios.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-comparison-framework&#34;&gt;The Comparison Framework&lt;/h2&gt;&#xA;&lt;p&gt;We&amp;rsquo;ll compare three approaches:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Managed Cloud&lt;/strong&gt;: AWS, GCP, Azure managed services&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;VPS&lt;/strong&gt;: Virtual private servers (Hetzner, DigitalOcean, Linode)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Home Server&lt;/strong&gt;: Physical hardware at home&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;For each, we&amp;rsquo;ll calculate:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Monthly recurring costs&lt;/li&gt;&#xA;&lt;li&gt;Setup/maintenance time (valued at $50/hour)&lt;/li&gt;&#xA;&lt;li&gt;Hidden costs&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;scenario-1-personal-blogportfolio&#34;&gt;Scenario 1: Personal Blog/Portfolio&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;: Static site, minimal traffic (&amp;lt;10k visits/month)&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Case for Boring Technology</title>
      <link>/posts/boring-technology/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/boring-technology/</guid>
      <description>&lt;p&gt;Every few months, a new framework promises to revolutionize development. And every few months, teams adopt it, struggle with immature tooling, and eventually rewrite in something more established. There&amp;rsquo;s a better way.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-innovation-token-budget&#34;&gt;The Innovation Token Budget&lt;/h2&gt;&#xA;&lt;p&gt;Dan McKinley&amp;rsquo;s concept of &amp;ldquo;innovation tokens&amp;rdquo; captures this well: every organization has a limited budget for adopting new, unproven technology. Spend them wisely.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;You probably get three.&lt;/strong&gt; Maybe.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re using:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A new programming language&lt;/li&gt;&#xA;&lt;li&gt;A new database&lt;/li&gt;&#xA;&lt;li&gt;A new deployment platform&lt;/li&gt;&#xA;&lt;li&gt;A new frontend framework&lt;/li&gt;&#xA;&lt;li&gt;A novel architecture pattern&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&amp;hellip;you&amp;rsquo;ve already overspent. When something breaks—and it will—you won&amp;rsquo;t know if it&amp;rsquo;s your code, the framework, or an obscure interaction between your five bleeding-edge choices.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Welcome to the Tech Blog</title>
      <link>/posts/welcome/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/welcome/</guid>
      <description>&lt;p&gt;Welcome to the tech blog! This is a place where I&amp;rsquo;ll be sharing articles about various technology topics.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-to-expect&#34;&gt;What to Expect&lt;/h2&gt;&#xA;&lt;p&gt;Here you&amp;rsquo;ll find posts covering:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Software development best practices&lt;/li&gt;&#xA;&lt;li&gt;System architecture and design patterns&lt;/li&gt;&#xA;&lt;li&gt;DevOps and infrastructure&lt;/li&gt;&#xA;&lt;li&gt;Security considerations&lt;/li&gt;&#xA;&lt;li&gt;New tools and technologies&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;code-examples&#34;&gt;Code Examples&lt;/h2&gt;&#xA;&lt;p&gt;Posts will include code examples with syntax highlighting:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;hello_world&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Stay tuned for more content!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing Shell Scripts That Don&#39;t Break</title>
      <link>/posts/shell-scripts-that-dont-break/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/shell-scripts-that-dont-break/</guid>
      <description>&lt;p&gt;Shell scripts are everywhere: CI pipelines, deployment automation, developer tooling. Yet most are fragile, failing unexpectedly when conditions change slightly. Here&amp;rsquo;s how to write scripts that hold up.&lt;/p&gt;&#xA;&lt;h2 id=&#34;start-with-strict-mode&#34;&gt;Start With Strict Mode&lt;/h2&gt;&#xA;&lt;p&gt;Always begin scripts with:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -euo pipefail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;What this does:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;set -e&lt;/code&gt;: Exit immediately if a command fails&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;set -u&lt;/code&gt;: Treat unset variables as errors&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;set -o pipefail&lt;/code&gt;: Pipeline fails if any command fails, not just the last&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;the-difference-this-makes&#34;&gt;The Difference This Makes&lt;/h3&gt;&#xA;&lt;p&gt;Without strict mode:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Developer Productivity Tips</title>
      <link>/posts/developer-productivity/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/developer-productivity/</guid>
      <description>&lt;p&gt;Productivity isn&amp;rsquo;t about working more hours. It&amp;rsquo;s about removing friction and focusing on what matters.&lt;/p&gt;&#xA;&lt;h2 id=&#34;keyboard-over-mouse&#34;&gt;Keyboard Over Mouse&lt;/h2&gt;&#xA;&lt;p&gt;Every trip to the mouse costs time. Learn shortcuts:&lt;/p&gt;&#xA;&lt;h3 id=&#34;essential-ide-shortcuts&#34;&gt;Essential IDE Shortcuts&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Action&lt;/th&gt;&#xA;          &lt;th&gt;VS Code&lt;/th&gt;&#xA;          &lt;th&gt;JetBrains&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Go to file&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+P&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+Shift+N&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Go to symbol&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+Shift+O&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+Alt+Shift+N&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Find in files&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+Shift+F&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+Shift+F&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Quick fix&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+.&lt;/td&gt;&#xA;          &lt;td&gt;Alt+Enter&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Rename&lt;/td&gt;&#xA;          &lt;td&gt;F2&lt;/td&gt;&#xA;          &lt;td&gt;Shift+F6&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Toggle terminal&lt;/td&gt;&#xA;          &lt;td&gt;Ctrl+`&lt;/td&gt;&#xA;          &lt;td&gt;Alt+F12&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;terminal-shortcuts&#34;&gt;Terminal Shortcuts&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Bash&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ctrl+R  &lt;span style=&#34;color:#75715e&#34;&gt;# Search history&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ctrl+A  &lt;span style=&#34;color:#75715e&#34;&gt;# Start of line&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ctrl+E  &lt;span style=&#34;color:#75715e&#34;&gt;# End of line&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ctrl+W  &lt;span style=&#34;color:#75715e&#34;&gt;# Delete word backward&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;!!      &lt;span style=&#34;color:#75715e&#34;&gt;# Repeat last command&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;!$      &lt;span style=&#34;color:#75715e&#34;&gt;# Last argument of previous command&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;automate-repetitive-tasks&#34;&gt;Automate Repetitive Tasks&lt;/h2&gt;&#xA;&lt;p&gt;If you do it twice, automate it:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Basics: Getting Started with Container Orchestration</title>
      <link>/posts/kubernetes-basics/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/kubernetes-basics/</guid>
      <description>&lt;p&gt;Kubernetes has become the standard for container orchestration. This guide covers the essential concepts you need to understand before diving in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-kubernetes&#34;&gt;What is Kubernetes?&lt;/h2&gt;&#xA;&lt;p&gt;Kubernetes (K8s) is an open-source platform for automating deployment, scaling, and management of containerized applications. Originally developed by Google, it&amp;rsquo;s now maintained by the Cloud Native Computing Foundation.&lt;/p&gt;&#xA;&lt;h2 id=&#34;core-concepts&#34;&gt;Core Concepts&lt;/h2&gt;&#xA;&lt;h3 id=&#34;pods&#34;&gt;Pods&lt;/h3&gt;&#xA;&lt;p&gt;The smallest deployable unit in Kubernetes. A pod can contain one or more containers that share storage and network.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Load Balancing Strategies Explained</title>
      <link>/posts/load-balancing/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/load-balancing/</guid>
      <description>&lt;p&gt;Load balancing distributes traffic across multiple servers. Here&amp;rsquo;s how different strategies work and when to use them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-load-balance&#34;&gt;Why Load Balance?&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Handle more traffic&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Availability&lt;/strong&gt;: Survive server failures&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Route to fastest server&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;algorithms&#34;&gt;Algorithms&lt;/h2&gt;&#xA;&lt;h3 id=&#34;round-robin&#34;&gt;Round Robin&lt;/h3&gt;&#xA;&lt;p&gt;Distribute requests sequentially:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Request 1 → Server A&#xA;Request 2 → Server B&#xA;Request 3 → Server C&#xA;Request 4 → Server A (cycle repeats)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nginx&#34; data-lang=&#34;nginx&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;upstream&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;backend&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;server&lt;/span&gt; 192.168.1.1;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;server&lt;/span&gt; 192.168.1.2;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;server&lt;/span&gt; 192.168.1.3;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Homogeneous servers, stateless applications.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mastering grep for Text Searching</title>
      <link>/posts/grep-mastery/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/grep-mastery/</guid>
      <description>&lt;p&gt;grep is one of the most powerful Unix tools. Master it, and you&amp;rsquo;ll find information faster than any IDE.&lt;/p&gt;&#xA;&lt;h2 id=&#34;basic-usage&#34;&gt;Basic Usage&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Search for pattern in file&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Search in multiple files&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt; *.log&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Recursive search&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -r &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;TODO&amp;#34;&lt;/span&gt; ./src&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;essential-flags&#34;&gt;Essential Flags&lt;/h2&gt;&#xA;&lt;h3 id=&#34;case-insensitivity&#34;&gt;Case Insensitivity&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Matches: error, Error, ERROR, eRrOr&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;line-numbers&#34;&gt;Line Numbers&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -n &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;function&amp;#34;&lt;/span&gt; script.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 10:function doSomething() {&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 25:function doAnother() {&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;count-matches&#34;&gt;Count Matches&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -c &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 42&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;invert-match&#34;&gt;Invert Match&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Show lines that DON&amp;#39;T match&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -v &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;debug&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;show-only-matching-part&#34;&gt;Show Only Matching Part&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error.*&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# error: connection refused&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# error: timeout&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;context-lines&#34;&gt;Context Lines&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3 lines before match&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -B &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;exception&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3 lines after match&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -A &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;exception&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3 lines before and after&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -C &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;exception&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;regular-expressions&#34;&gt;Regular Expressions&lt;/h2&gt;&#xA;&lt;h3 id=&#34;basic-patterns&#34;&gt;Basic Patterns&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Any character&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;err.r&amp;#34;&lt;/span&gt; logfile.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# error, errar, err0r&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Start of line&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^Error&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# End of line&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed&lt;/span&gt;$&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Zero or more&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;go*gle&amp;#34;&lt;/span&gt; file.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# ggle, gogle, google, gooogle&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;extended-regex--e&#34;&gt;Extended Regex (-E)&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# One or more&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;go+gle&amp;#34;&lt;/span&gt; file.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# gogle, google, gooogle&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Optional&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;colou?r&amp;#34;&lt;/span&gt; file.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# color, colour&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Alternation&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error|warning|fatal&amp;#34;&lt;/span&gt; logfile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Grouping&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;(ab)+&amp;#34;&lt;/span&gt; file.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# ab, abab, ababab&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;character-classes&#34;&gt;Character Classes&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Digits&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[0-9]&amp;#34;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Letters&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[a-zA-Z]&amp;#34;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Not these characters&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[^0-9]&amp;#34;&lt;/span&gt; file.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# Non-digits&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Word characters&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\w+&amp;#34;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;practical-examples&#34;&gt;Practical Examples&lt;/h2&gt;&#xA;&lt;h3 id=&#34;find-ip-addresses&#34;&gt;Find IP Addresses&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b&amp;#34;&lt;/span&gt; access.log&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;find-email-addresses&#34;&gt;Find Email Addresses&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}&amp;#34;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;find-function-definitions&#34;&gt;Find Function Definitions&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Python&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^def \w+\(&amp;#34;&lt;/span&gt; *.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# JavaScript&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;(function \w+|const \w+ = .*=&amp;gt;)&amp;#34;&lt;/span&gt; *.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;find-todo-comments&#34;&gt;Find TODO Comments&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -rn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;TODO\|FIXME\|HACK&amp;#34;&lt;/span&gt; ./src&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;find-empty-lines&#34;&gt;Find Empty Lines&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -c &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^&lt;/span&gt;$&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;combining-with-other-commands&#34;&gt;Combining with Other Commands&lt;/h2&gt;&#xA;&lt;h3 id=&#34;with-find&#34;&gt;With find&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Search specific file types&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;find . -name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.py&amp;#34;&lt;/span&gt; -exec grep -l &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;import requests&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{}&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Or with xargs&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;find . -name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.py&amp;#34;&lt;/span&gt; | xargs grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;import requests&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;with-ps&#34;&gt;With ps&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Find process&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps aux | grep nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;with-history&#34;&gt;With history&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Search command history&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;history | grep docker&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;with-pipe&#34;&gt;With pipe&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Count errors per type&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat logfile.txt | grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt; | sort | uniq -c | sort -rn&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;performance-tips&#34;&gt;Performance Tips&lt;/h2&gt;&#xA;&lt;h3 id=&#34;use-fixed-strings--f&#34;&gt;Use Fixed Strings (-F)&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Faster when you don&amp;#39;t need regex&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -F &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;exact string&amp;#34;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;limit-output--m&#34;&gt;Limit Output (-m)&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Stop after 10 matches&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -m &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pattern&amp;#34;&lt;/span&gt; hugefile.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;binary-files&#34;&gt;Binary Files&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Treat binary as text&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pattern&amp;#34;&lt;/span&gt; binaryfile&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Skip binary files&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep -I &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pattern&amp;#34;&lt;/span&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;ripgrep-a-faster-alternative&#34;&gt;ripgrep: A Faster Alternative&lt;/h2&gt;&#xA;&lt;p&gt;If you search code often:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Microservices Patterns That Work</title>
      <link>/posts/microservices-patterns/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/microservices-patterns/</guid>
      <description>&lt;p&gt;Microservices are not an architecture you adopt because they are modern; they are a trade you make because an organization has grown past what a single deployable unit can absorb. The honest framing, which most enthusiastic adoptions skip, is that you are exchanging one category of difficulty for another. A monolith&amp;rsquo;s problems are real but &lt;em&gt;legible&lt;/em&gt;: a tangled call graph, a shared database everyone is afraid to migrate, a deploy that takes the whole app down. Microservices dissolve those and hand you a different bag — every in-process function call that used to either succeed or throw is now a network request that can also hang, time out, partially succeed, or succeed-but-the-response-got-lost. You have traded a complexity you can see in a stack trace for a complexity that lives in the gaps between services, and the patterns in this piece exist to make that second category survivable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Password Security Done Right</title>
      <link>/posts/password-security/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/password-security/</guid>
      <description>&lt;p&gt;Password security seems simple but is often done wrong. Here&amp;rsquo;s how to handle passwords correctly.&lt;/p&gt;&#xA;&lt;h2 id=&#34;never-store-plain-text&#34;&gt;Never Store Plain Text&lt;/h2&gt;&#xA;&lt;p&gt;This should be obvious, but breaches still reveal plain text passwords. Always hash.&lt;/p&gt;&#xA;&lt;h2 id=&#34;use-the-right-algorithm&#34;&gt;Use the Right Algorithm&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;Good choices:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;bcrypt&lt;/li&gt;&#xA;&lt;li&gt;Argon2 (preferred for new projects)&lt;/li&gt;&#xA;&lt;li&gt;scrypt&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;Never use:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;MD5&lt;/li&gt;&#xA;&lt;li&gt;SHA-1&lt;/li&gt;&#xA;&lt;li&gt;SHA-256 alone (too fast)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;bcrypt-example&#34;&gt;bcrypt Example&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; bcrypt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Hashing&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;password &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user_password&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;salt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bcrypt&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;gensalt(rounds&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hashed &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bcrypt&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hashpw(password, salt)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Verification&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; bcrypt&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;checkpw(password, hashed):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Password matches&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Node.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bcrypt&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;bcrypt&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Hash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;hash&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bcrypt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;hash&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;password&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Verify&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;match&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bcrypt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;compare&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;password&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;hash&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;work-factor-matters&#34;&gt;Work Factor Matters&lt;/h2&gt;&#xA;&lt;p&gt;The &amp;ldquo;rounds&amp;rdquo; or &amp;ldquo;cost&amp;rdquo; parameter controls how slow hashing is:&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Art of Code Review</title>
      <link>/posts/code-review-guide/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/code-review-guide/</guid>
      <description>&lt;p&gt;The most common mistake teams make about code review is believing its purpose is to catch bugs. It catches some, but it is mediocre at it: a reviewer skimming a diff on a Tuesday afternoon will miss the race condition, the off-by-one, and the unhandled error that a test or a type checker would have caught deterministically. If bug-catching were the goal, the rational conclusion would be to automate review away. The reason code review survives — the reason every serious engineering organization mandates it — is that its real products are the things only humans can produce: shared understanding of the codebase, pressure on design before it ossifies, a propagating sense of the team&amp;rsquo;s standards, and the simple fact that after a review at least two people understand any given change. A team where only one person understands each subsystem is a team one resignation away from a crisis. Review is the mechanism that prevents that, and bug-catching is a bonus.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is Linux? A Beginner&#39;s Introduction</title>
      <link>/posts/linux-introduction/</link>
      <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-introduction/</guid>
      <description>&lt;p&gt;Linux powers most of the internet, runs on everything from smartphones to supercomputers, and is essential knowledge for anyone in tech. Here&amp;rsquo;s what you need to know.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-linux&#34;&gt;What is Linux?&lt;/h2&gt;&#xA;&lt;p&gt;Linux is an open-source operating system kernel created by Linus Torvalds in 1991. When people say &amp;ldquo;Linux,&amp;rdquo; they usually mean a complete operating system (called a &amp;ldquo;distribution&amp;rdquo;) built around the Linux kernel.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-linux-family-tree&#34;&gt;The Linux Family Tree&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Linux Kernel (Linus Torvalds, 1991)&#xA;    │&#xA;    ├── Debian Family&#xA;    │   ├── Debian&#xA;    │   ├── Ubuntu&#xA;    │   └── Linux Mint&#xA;    │&#xA;    ├── Red Hat Family&#xA;    │   ├── RHEL (Red Hat Enterprise Linux)&#xA;    │   ├── CentOS / Rocky Linux / AlmaLinux&#xA;    │   └── Fedora&#xA;    │&#xA;    ├── Arch Family&#xA;    │   ├── Arch Linux&#xA;    │   └── Manjaro&#xA;    │&#xA;    └── Others&#xA;        ├── SUSE&#xA;        ├── Gentoo&#xA;        └── Alpine&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;why-linux-matters&#34;&gt;Why Linux Matters&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-servers-run-linux&#34;&gt;1. Servers Run Linux&lt;/h3&gt;&#xA;&lt;p&gt;Over 90% of web servers run Linux. If you deploy applications, you need Linux skills.&lt;/p&gt;</description>
    </item>
    <item>
      <title>awk: The Text Processing Powerhouse</title>
      <link>/posts/awk-tutorial/</link>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/awk-tutorial/</guid>
      <description>&lt;p&gt;awk is a programming language designed for text processing. It excels at extracting and transforming columnar data.&lt;/p&gt;&#xA;&lt;h2 id=&#34;basic-syntax&#34;&gt;Basic Syntax&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;pattern { action }&amp;#39;&lt;/span&gt; file&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;If pattern matches, action is executed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;printing-columns&#34;&gt;Printing Columns&lt;/h2&gt;&#xA;&lt;p&gt;awk splits each line into fields:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Print first column&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{ print $1 }&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Print first and third columns&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{ print $1, $3 }&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Print entire line&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{ print $0 }&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;field-separator&#34;&gt;Field Separator&lt;/h2&gt;&#xA;&lt;p&gt;Default is whitespace. Change with -F:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Database Design Fundamentals</title>
      <link>/posts/database-design/</link>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/database-design/</guid>
      <description>&lt;p&gt;Good database design prevents countless headaches. Here are the fundamentals that matter.&lt;/p&gt;&#xA;&lt;h2 id=&#34;normalization-basics&#34;&gt;Normalization Basics&lt;/h2&gt;&#xA;&lt;h3 id=&#34;first-normal-form-1nf&#34;&gt;First Normal Form (1NF)&lt;/h3&gt;&#xA;&lt;p&gt;No repeating groups:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- Bad&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; orders (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    id INT,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    items TEXT  &lt;span style=&#34;color:#75715e&#34;&gt;-- &amp;#34;item1,item2,item3&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- Good&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; orders (id INT &lt;span style=&#34;color:#66d9ef&#34;&gt;PRIMARY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;KEY&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; order_items (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    order_id INT &lt;span style=&#34;color:#66d9ef&#34;&gt;REFERENCES&lt;/span&gt; orders(id),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    item_id INT,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    quantity INT&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;second-normal-form-2nf&#34;&gt;Second Normal Form (2NF)&lt;/h3&gt;&#xA;&lt;p&gt;No partial dependencies:&lt;/p&gt;</description>
    </item>
    <item>
      <title>DNS Deep Dive for Developers</title>
      <link>/posts/dns-deep-dive/</link>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/dns-deep-dive/</guid>
      <description>&lt;p&gt;DNS is the internet&amp;rsquo;s phone book. Understanding it helps you troubleshoot issues and configure services correctly.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-dns-works&#34;&gt;How DNS Works&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Browser: &amp;#34;What&amp;#39;s the IP for example.com?&amp;#34;&#xA;    ↓&#xA;Local Resolver → Root Server → TLD Server → Authoritative Server&#xA;    ↓&#xA;Answer: &amp;#34;93.184.216.34&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;record-types&#34;&gt;Record Types&lt;/h2&gt;&#xA;&lt;h3 id=&#34;a-record&#34;&gt;A Record&lt;/h3&gt;&#xA;&lt;p&gt;Maps domain to IPv4 address:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;example.com.    A    93.184.216.34&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;aaaa-record&#34;&gt;AAAA Record&lt;/h3&gt;&#xA;&lt;p&gt;Maps domain to IPv6 address:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;example.com.    AAAA    2606:2800:220:1:248:1893:25c8:1946&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;cname-record&#34;&gt;CNAME Record&lt;/h3&gt;&#xA;&lt;p&gt;Alias to another domain:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;www.example.com.    CNAME    example.com.&#xA;blog.example.com.   CNAME    myblog.ghost.io.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Can&amp;rsquo;t coexist with other records at same name.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux File System Hierarchy Explained</title>
      <link>/posts/linux-filesystem-hierarchy/</link>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-filesystem-hierarchy/</guid>
      <description>&lt;p&gt;Linux has a standardized directory structure. Understanding it helps you navigate any Linux system and know where to find (or put) things.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-root-of-everything&#34;&gt;The Root of Everything&lt;/h2&gt;&#xA;&lt;p&gt;Everything starts at &lt;code&gt;/&lt;/code&gt; (root). Unlike Windows with drive letters (C:, D:), Linux has a single unified tree.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/&#xA;├── bin&#xA;├── boot&#xA;├── dev&#xA;├── etc&#xA;├── home&#xA;├── lib&#xA;├── media&#xA;├── mnt&#xA;├── opt&#xA;├── proc&#xA;├── root&#xA;├── run&#xA;├── sbin&#xA;├── srv&#xA;├── sys&#xA;├── tmp&#xA;├── usr&#xA;└── var&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;directory-breakdown&#34;&gt;Directory Breakdown&lt;/h2&gt;&#xA;&lt;h3 id=&#34;bin---essential-binaries&#34;&gt;/bin - Essential Binaries&lt;/h3&gt;&#xA;&lt;p&gt;Basic commands needed for single-user mode and system recovery:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Systematic Debugging Strategies</title>
      <link>/posts/debugging-strategies/</link>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/debugging-strategies/</guid>
      <description>&lt;p&gt;The difference between an engineer who fixes a bug in twenty minutes and one who fixes it in two days is almost never raw intelligence. It is method. The slow engineer reads the code, forms a guess, changes something, reruns, and repeats — a random walk through the solution space that occasionally stumbles onto the answer and just as often introduces a second bug while chasing the first. The fast engineer treats the bug as a falsifiable claim about a system and spends their effort &lt;em&gt;narrowing&lt;/em&gt;: cutting the space of possible causes in half, then in half again, until only one explanation survives. Debugging is applied epistemology. The tools — debuggers, logs, tracers, &lt;code&gt;git bisect&lt;/code&gt; — are only useful in service of that narrowing, and used without it they generate noise faster than insight.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Technical Writing for Developers</title>
      <link>/posts/technical-writing/</link>
      <pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/technical-writing/</guid>
      <description>&lt;p&gt;Good technical writing is a superpower. It scales your knowledge and helps your team move faster.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-inverted-pyramid&#34;&gt;The Inverted Pyramid&lt;/h2&gt;&#xA;&lt;p&gt;Put the most important information first:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Most Important (what, why)&#xA;        ↓&#xA;Supporting Details (how)&#xA;        ↓&#xA;Background (context)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Don&amp;rsquo;t make readers wade through history to find what they need.&lt;/p&gt;&#xA;&lt;h2 id=&#34;readme-structure&#34;&gt;README Structure&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;22&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;23&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;24&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;25&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;26&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;27&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;28&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;29&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;30&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;31&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;32&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;33&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;34&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;35&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;36&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Project Name&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;One-line description of what this does.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## Quick Start&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;\`\`\`bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install myproject&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm start&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;\`\`\`&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## Features&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;-&lt;/span&gt; Feature 1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;-&lt;/span&gt; Feature 2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;-&lt;/span&gt; Feature 3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## Installation&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Detailed installation steps...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## Usage&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Examples of common use cases...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## Configuration&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Available options...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## Contributing&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;How to contribute...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## License&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MIT&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;write-for-scanning&#34;&gt;Write for Scanning&lt;/h2&gt;&#xA;&lt;p&gt;People scan before they read:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Caching Strategies for Performance</title>
      <link>/posts/caching-strategies/</link>
      <pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/caching-strategies/</guid>
      <description>&lt;p&gt;Caching is the most effective way to improve performance. Here&amp;rsquo;s how to do it right.&lt;/p&gt;&#xA;&lt;h2 id=&#34;cache-layers&#34;&gt;Cache Layers&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Client → CDN Cache → App Cache → Database Cache → Database&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each layer reduces load on the next.&lt;/p&gt;&#xA;&lt;h2 id=&#34;common-patterns&#34;&gt;Common Patterns&lt;/h2&gt;&#xA;&lt;h3 id=&#34;cache-aside-lazy-loading&#34;&gt;Cache-Aside (Lazy Loading)&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_user&lt;/span&gt;(user_id):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Check cache&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cached &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; redis&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;user_id&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; cached:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;loads(cached)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Load from database&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    user &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; db&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;query(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;SELECT * FROM users WHERE id = ?&amp;#34;&lt;/span&gt;, user_id)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# Store in cache&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    redis&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;setex(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;user_id&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;3600&lt;/span&gt;, json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(user))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; user&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Only caches what&amp;rsquo;s needed&#xA;&lt;strong&gt;Cons:&lt;/strong&gt; Cache miss penalty, potential stale data&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Learn New Technologies Effectively</title>
      <link>/posts/learning-new-technologies/</link>
      <pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/learning-new-technologies/</guid>
      <description>&lt;p&gt;Technology changes fast. Being able to learn quickly is more valuable than any specific skill.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-learning-framework&#34;&gt;The Learning Framework&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-understand-the-why&#34;&gt;1. Understand the Why&lt;/h3&gt;&#xA;&lt;p&gt;Before diving in, answer:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;What problem does this solve?&lt;/li&gt;&#xA;&lt;li&gt;Why was it created?&lt;/li&gt;&#xA;&lt;li&gt;What are the alternatives?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Understanding context helps you learn faster and know when to use it.&lt;/p&gt;&#xA;&lt;h3 id=&#34;2-get-something-running&#34;&gt;2. Get Something Running&lt;/h3&gt;&#xA;&lt;p&gt;Don&amp;rsquo;t read documentation for hours. Get a working example:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Most frameworks have a quick start&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npx create-react-app my-app&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rails new myapp&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo new myproject&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Modify it. Break it. Fix it. This builds intuition.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux File Permissions Demystified</title>
      <link>/posts/linux-file-permissions/</link>
      <pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-file-permissions/</guid>
      <description>&lt;p&gt;File permissions are fundamental to Linux security. They control who can read, write, and execute files. Here&amp;rsquo;s everything you need to know.&lt;/p&gt;&#xA;&lt;h2 id=&#34;understanding-permission-bits&#34;&gt;Understanding Permission Bits&lt;/h2&gt;&#xA;&lt;p&gt;Every file has three permission sets:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-rwxr-xr-- 1 alice developers 1234 Jan 10 10:00 script.sh&#xA;│├─┤├─┤├─┤&#xA;│ │  │  └── Others (everyone else)&#xA;│ │  └───── Group (developers)&#xA;│ └──────── Owner (alice)&#xA;└────────── File type (- = regular file)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;permission-types&#34;&gt;Permission Types&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Symbol&lt;/th&gt;&#xA;          &lt;th&gt;Permission&lt;/th&gt;&#xA;          &lt;th&gt;For Files&lt;/th&gt;&#xA;          &lt;th&gt;For Directories&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Read&lt;/td&gt;&#xA;          &lt;td&gt;View contents&lt;/td&gt;&#xA;          &lt;td&gt;List contents&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;w&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Write&lt;/td&gt;&#xA;          &lt;td&gt;Modify file&lt;/td&gt;&#xA;          &lt;td&gt;Create/delete files&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Execute&lt;/td&gt;&#xA;          &lt;td&gt;Run as program&lt;/td&gt;&#xA;          &lt;td&gt;Enter directory&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;file-types&#34;&gt;File Types&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Symbol&lt;/th&gt;&#xA;          &lt;th&gt;Type&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Regular file&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Directory&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;l&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Symbolic link&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Block device&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Character device&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Socket&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;p&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Named pipe&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;numeric-octal-notation&#34;&gt;Numeric (Octal) Notation&lt;/h2&gt;&#xA;&lt;p&gt;Permissions can be expressed as numbers:&lt;/p&gt;</description>
    </item>
    <item>
      <title>sed: Stream Editor Essentials</title>
      <link>/posts/sed-tutorial/</link>
      <pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/sed-tutorial/</guid>
      <description>&lt;p&gt;sed (stream editor) transforms text line by line. It&amp;rsquo;s perfect for find-and-replace operations and text manipulation.&lt;/p&gt;&#xA;&lt;h2 id=&#34;basic-substitution&#34;&gt;Basic Substitution&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Replace first occurrence per line&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/old/new/&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Replace all occurrences (global)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/old/new/g&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Replace nth occurrence&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/old/new/2&amp;#39;&lt;/span&gt; file.txt  &lt;span style=&#34;color:#75715e&#34;&gt;# Second occurrence&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;in-place-editing&#34;&gt;In-Place Editing&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Edit file directly&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/old/new/g&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# With backup (safer)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i.bak &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/old/new/g&amp;#39;&lt;/span&gt; file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;macOS note:&lt;/strong&gt; Requires &lt;code&gt;sed -i &#39;&#39; &#39;s/old/new/g&#39; file.txt&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Testing Strategies That Actually Work</title>
      <link>/posts/testing-strategies/</link>
      <pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/testing-strategies/</guid>
      <description>&lt;p&gt;A test suite is not a correctness proof and was never going to be one. Dijkstra&amp;rsquo;s line — testing shows the presence of bugs, never their absence — is true and worth remembering, but it leads people to the wrong conclusion. The point of testing is not to prove the code is right; it is to buy &lt;em&gt;confidence to change the code&lt;/em&gt;. A codebase with a good suite is one where an engineer can refactor a module, add a feature, or upgrade a dependency and find out within seconds whether they broke something, instead of finding out three weeks later from a customer. That confidence is the product. Everything else — coverage numbers, the testing pyramid, TDD, the choice between mocks and fakes — is in service of maximizing that confidence per unit of effort, because the effort is finite and the tests themselves are code you have to maintain forever.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Career Advice for Software Developers</title>
      <link>/posts/career-advice/</link>
      <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/career-advice/</guid>
      <description>&lt;p&gt;Career advice is personal, but some patterns hold across most situations. Here&amp;rsquo;s what I&amp;rsquo;ve learned.&lt;/p&gt;&#xA;&lt;h2 id=&#34;technical-skills-are-necessary-but-not-sufficient&#34;&gt;Technical Skills Are Necessary But Not Sufficient&lt;/h2&gt;&#xA;&lt;p&gt;Being a great coder isn&amp;rsquo;t enough:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Can you communicate your ideas?&lt;/li&gt;&#xA;&lt;li&gt;Do people want to work with you?&lt;/li&gt;&#xA;&lt;li&gt;Can you understand business needs?&lt;/li&gt;&#xA;&lt;li&gt;Do you deliver on commitments?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;The best developers I know combine technical skills with soft skills.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;invest-in-fundamentals&#34;&gt;Invest in Fundamentals&lt;/h2&gt;&#xA;&lt;p&gt;Frameworks change. Fundamentals don&amp;rsquo;t:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Data structures and algorithms&lt;/li&gt;&#xA;&lt;li&gt;System design&lt;/li&gt;&#xA;&lt;li&gt;Networking basics&lt;/li&gt;&#xA;&lt;li&gt;Operating system concepts&lt;/li&gt;&#xA;&lt;li&gt;Security principles&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Learn React, but also learn why it works.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Effective Log Management Strategies</title>
      <link>/posts/log-management/</link>
      <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/log-management/</guid>
      <description>&lt;p&gt;Logs are the cheapest telemetry to produce and the most expensive to keep, and almost every team discovers that ordering the hard way — usually when the observability bill arrives or when a 2 a.m. incident turns into an unsearchable wall of text. Good log management is not about choosing a vendor; it is a set of disciplines applied at the source, in the pipeline, and at query time, that together decide whether your logs are a debugging instrument or a write-only landfill you pay rent on. This post is about those disciplines: how to structure logs so they are queryable, how to think about the cost model before it thinks about you, what to drop before it ever hits storage, and how to keep logs useful and compliant over their whole lifecycle. For tool-by-tool comparisons I will point at the &lt;a href=&#34;/posts/modern-logging-architecture/&#34;&gt;modern logging architecture&lt;/a&gt; shootout and the &lt;a href=&#34;/posts/loki-log-aggregation/&#34;&gt;Loki deep-dive&lt;/a&gt; rather than re-litigate them here.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Event-Driven Architecture Explained</title>
      <link>/posts/event-driven-architecture/</link>
      <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/event-driven-architecture/</guid>
      <description>&lt;p&gt;Event-driven architecture is the practice of building systems where components communicate by announcing that something happened rather than by calling each other directly, and its appeal is real: a service that emits an &lt;code&gt;OrderPlaced&lt;/code&gt; event does not need to know that an email service, an inventory service, and an analytics pipeline all care. You can add a fourth consumer without touching the producer. That decoupling is genuinely powerful, and it is also where most of the difficulty hides. The moment you replace a function call with an event, you inherit a distributed-systems problem: messages can be delivered twice, arrive out of order, or vanish; the producer and its database can disagree about whether an event was sent; and a bug now spans five services with no single stack trace to read. This post is about both halves — the patterns that make event-driven systems work, and the honest costs that decide whether you should build one at all. For the deep specialist topics it touches, I will point at the &lt;a href=&#34;/posts/event-sourcing-and-cqrs/&#34;&gt;event sourcing and CQRS&lt;/a&gt;, &lt;a href=&#34;/posts/outbox-pattern/&#34;&gt;outbox pattern&lt;/a&gt;, and &lt;a href=&#34;/posts/apache-kafka-deep-dive/&#34;&gt;Kafka&lt;/a&gt; posts rather than re-derive them here.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Package Management: apt, yum, and Beyond</title>
      <link>/posts/linux-package-management/</link>
      <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-package-management/</guid>
      <description>&lt;p&gt;Package managers handle installing, updating, and removing software. Different Linux families use different tools, but the concepts are similar.&lt;/p&gt;&#xA;&lt;h2 id=&#34;package-manager-overview&#34;&gt;Package Manager Overview&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Distribution&lt;/th&gt;&#xA;          &lt;th&gt;Package Format&lt;/th&gt;&#xA;          &lt;th&gt;Package Manager&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Debian, Ubuntu&lt;/td&gt;&#xA;          &lt;td&gt;.deb&lt;/td&gt;&#xA;          &lt;td&gt;apt, dpkg&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;RHEL, CentOS, Fedora&lt;/td&gt;&#xA;          &lt;td&gt;.rpm&lt;/td&gt;&#xA;          &lt;td&gt;dnf/yum, rpm&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Arch&lt;/td&gt;&#xA;          &lt;td&gt;.pkg.tar.zst&lt;/td&gt;&#xA;          &lt;td&gt;pacman&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Alpine&lt;/td&gt;&#xA;          &lt;td&gt;.apk&lt;/td&gt;&#xA;          &lt;td&gt;apk&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;SUSE&lt;/td&gt;&#xA;          &lt;td&gt;.rpm&lt;/td&gt;&#xA;          &lt;td&gt;zypper&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;apt-debianubuntu&#34;&gt;APT (Debian/Ubuntu)&lt;/h2&gt;&#xA;&lt;h3 id=&#34;update-package-lists&#34;&gt;Update Package Lists&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Update available package info&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt update&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Upgrade installed packages&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt upgrade&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Full upgrade (handles dependencies)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt full-upgrade&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;installing-packages&#34;&gt;Installing Packages&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install single package&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt install nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install multiple packages&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt install nginx postgresql redis&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install specific version&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt install nginx&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1.18.0-0ubuntu1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install without prompts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt install -y nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;removing-packages&#34;&gt;Removing Packages&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Remove package (keep config)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt remove nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Remove package and config&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt purge nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Remove unused dependencies&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt autoremove&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;searching&#34;&gt;Searching&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Search by name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt search nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Show package info&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt show nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# List installed packages&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt list --installed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# List upgradable packages&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt list --upgradable&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;cache-management&#34;&gt;Cache Management&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Clean package cache&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt clean&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Remove old package versions&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt autoclean&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;dpkg-low-level&#34;&gt;dpkg (Low-Level)&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install .deb file&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo dpkg -i package.deb&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# List installed packages&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dpkg -l&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Find which package owns a file&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dpkg -S /usr/bin/nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# List files in package&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dpkg -L nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;dnfyum-rhelfedora&#34;&gt;DNF/YUM (RHEL/Fedora)&lt;/h2&gt;&#xA;&lt;p&gt;DNF is the modern replacement for YUM. Commands are mostly compatible.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Refactoring Legacy Code Safely</title>
      <link>/posts/refactoring-legacy-code/</link>
      <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/refactoring-legacy-code/</guid>
      <description>&lt;p&gt;Michael Feathers gave the field its most useful definition: legacy code is code without tests. Not code that is old, not code written in an unfashionable language, not code by a developer who has left — those are incidental. The defining property is that you cannot change it with confidence, because nothing tells you when you have broken it. A pristine, idiomatic, beautifully formatted module with no test coverage is legacy code; a crusty twenty-year-old C function wrapped in a thousand assertions is not. This reframing matters because it tells you exactly what to do first: the path out of fear is not to rewrite, and not to &amp;ldquo;clean up,&amp;rdquo; but to &lt;em&gt;establish a safety net&lt;/em&gt; so that every subsequent change is verifiable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>xargs: Building Commands from Input</title>
      <link>/posts/xargs-tutorial/</link>
      <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/xargs-tutorial/</guid>
      <description>&lt;p&gt;xargs reads items from input and executes a command with those items as arguments. It&amp;rsquo;s the glue that connects commands together.&lt;/p&gt;&#xA;&lt;h2 id=&#34;basic-usage&#34;&gt;Basic Usage&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Simple example&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;file1 file2 file3&amp;#34;&lt;/span&gt; | xargs rm&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Equivalent to:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rm file1 file2 file3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;from-find&#34;&gt;From find&lt;/h2&gt;&#xA;&lt;p&gt;The most common pairing:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Delete all .tmp files&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;find . -name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.tmp&amp;#34;&lt;/span&gt; | xargs rm&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# More safely with -print0 and -0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;find . -name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.tmp&amp;#34;&lt;/span&gt; -print0 | xargs -0 rm&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;-print0&lt;/code&gt; and &lt;code&gt;-0&lt;/code&gt; handle filenames with spaces.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux User and Group Management</title>
      <link>/posts/linux-user-management/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-user-management/</guid>
      <description>&lt;p&gt;User and group management is fundamental to Linux administration. Here&amp;rsquo;s how to manage accounts and access control.&lt;/p&gt;&#xA;&lt;h2 id=&#34;understanding-users-and-groups&#34;&gt;Understanding Users and Groups&lt;/h2&gt;&#xA;&lt;h3 id=&#34;key-files&#34;&gt;Key Files&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;File&lt;/th&gt;&#xA;          &lt;th&gt;Purpose&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;/etc/passwd&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;User account information&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;/etc/shadow&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Encrypted passwords&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;/etc/group&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Group definitions&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;/etc/gshadow&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Group passwords (rarely used)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;etcpasswd-format&#34;&gt;/etc/passwd Format&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;username:x:UID:GID:comment:home:shell&#xA;alice:x:1001:1001:Alice Smith:/home/alice:/bin/bash&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;etcshadow-format&#34;&gt;/etc/shadow Format&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;username:password_hash:lastchange:min:max:warn:inactive:expire&#xA;alice:$6$rounds=...:19000:0:99999:7:::&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;etcgroup-format&#34;&gt;/etc/group Format&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;groupname:x:GID:members&#xA;developers:x:1002:alice,bob,charlie&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;creating-users&#34;&gt;Creating Users&lt;/h2&gt;&#xA;&lt;h3 id=&#34;useradd-low-level&#34;&gt;useradd (Low-Level)&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Basic user creation&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo useradd alice&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# With options&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo useradd -m -s /bin/bash -c &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Alice Smith&amp;#34;&lt;/span&gt; alice&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Options:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Managing SSL Certificates</title>
      <link>/posts/ssl-certificates/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/ssl-certificates/</guid>
      <description>&lt;p&gt;SSL/TLS certificates enable HTTPS. Here&amp;rsquo;s everything you need to know about managing them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;certificate-types&#34;&gt;Certificate Types&lt;/h2&gt;&#xA;&lt;h3 id=&#34;domain-validated-dv&#34;&gt;Domain Validated (DV)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Verifies domain ownership only&lt;/li&gt;&#xA;&lt;li&gt;Cheapest/free (Let&amp;rsquo;s Encrypt)&lt;/li&gt;&#xA;&lt;li&gt;Good for most sites&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;organization-validated-ov&#34;&gt;Organization Validated (OV)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Verifies organization exists&lt;/li&gt;&#xA;&lt;li&gt;More trust indicators&lt;/li&gt;&#xA;&lt;li&gt;Good for businesses&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;extended-validation-ev&#34;&gt;Extended Validation (EV)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Extensive verification&lt;/li&gt;&#xA;&lt;li&gt;Green bar (historically)&lt;/li&gt;&#xA;&lt;li&gt;Expensive, decreasing value&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;certificate-anatomy&#34;&gt;Certificate Anatomy&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN CERTIFICATE-----&#xA;MIIFazCCBFOgAwIBAgISA...&#xA;-----END CERTIFICATE-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Contains:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Subject (your domain)&lt;/li&gt;&#xA;&lt;li&gt;Issuer (who signed it)&lt;/li&gt;&#xA;&lt;li&gt;Validity period&lt;/li&gt;&#xA;&lt;li&gt;Public key&lt;/li&gt;&#xA;&lt;li&gt;Signature&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;lets-encrypt-with-certbot&#34;&gt;Let&amp;rsquo;s Encrypt with Certbot&lt;/h2&gt;&#xA;&lt;p&gt;Free, automated certificates:&lt;/p&gt;</description>
    </item>
    <item>
      <title>REST API Design Principles</title>
      <link>/posts/api-design-principles/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/api-design-principles/</guid>
      <description>&lt;p&gt;A well-designed API is intuitive to use and hard to misuse, and the difference between the two is almost never about clever features — it is about a handful of boring contracts kept consistently across every endpoint. The reason API design has principles at all is that an API is a promise to people you will never meet, who will build on your guarantees and curse your inconsistencies for years. Once a client depends on a behavior, that behavior is load-bearing whether you intended it or not, which makes the cheap-to-change decisions you make on day one expensive to change on day one thousand. This post walks the principles that survive contact with real traffic: how to model resources, what HTTP methods actually promise, how to return errors that a machine can act on, how to paginate without lying about consistency, how to version without breaking the world, and how to make unsafe operations safe to retry.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Twelve-Factor App Methodology</title>
      <link>/posts/twelve-factor-app/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/twelve-factor-app/</guid>
      <description>&lt;p&gt;The twelve-factor methodology, written by Heroku&amp;rsquo;s Adam Wiggins in 2011, is one of those documents whose influence is so total that its ideas now read as obvious — which is exactly the sign of a document that won. When it was published, &amp;ldquo;store config in environment variables,&amp;rdquo; &amp;ldquo;treat your app as a stateless process,&amp;rdquo; and &amp;ldquo;log to stdout and let the platform route it&amp;rdquo; were contrarian positions; today they are the unstated assumptions baked into Docker, Kubernetes, and every platform-as-a-service. The manifesto&amp;rsquo;s real subject is not twelve unrelated rules but a single property: an application that can be &lt;strong&gt;torn down and reconstructed anywhere&lt;/strong&gt; from nothing but its source code and a set of config values. Everything follows from wanting that property — the ability to run an identical app on a laptop, in CI, in staging, and across a hundred production instances, differing only in configuration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Thriving as a Remote Developer</title>
      <link>/posts/remote-work-tips/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/remote-work-tips/</guid>
      <description>&lt;p&gt;Remote work offers freedom but requires intentional effort. Here&amp;rsquo;s how to make it work.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-a-dedicated-workspace&#34;&gt;Create a Dedicated Workspace&lt;/h2&gt;&#xA;&lt;p&gt;You need a space that signals &amp;ldquo;work&amp;rdquo;:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Separate room if possible&lt;/li&gt;&#xA;&lt;li&gt;Consistent location if not&lt;/li&gt;&#xA;&lt;li&gt;Ergonomic setup (invest in good chair)&lt;/li&gt;&#xA;&lt;li&gt;Minimal distractions&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;When you&amp;rsquo;re in the workspace, you&amp;rsquo;re working. When you leave, you&amp;rsquo;re done.&lt;/p&gt;&#xA;&lt;h2 id=&#34;establish-routines&#34;&gt;Establish Routines&lt;/h2&gt;&#xA;&lt;p&gt;Without an office, you create structure:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;8:00 AM - Morning routine, coffee&#xA;8:30 AM - Check messages, plan day&#xA;9:00 AM - Deep work block&#xA;12:00 PM - Lunch, walk&#xA;1:00 PM - Meetings (if any)&#xA;3:00 PM - Second deep work block&#xA;5:30 PM - Wrap up, next day prep&#xA;6:00 PM - Done&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Routines reduce decision fatigue and create boundaries.&lt;/p&gt;</description>
    </item>
    <item>
      <title>tmux: Terminal Multiplexer Essentials</title>
      <link>/posts/tmux-essentials/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/tmux-essentials/</guid>
      <description>&lt;p&gt;tmux lets you run multiple terminal sessions in one window, detach them, and reattach later. Essential for remote work.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-tmux&#34;&gt;Why tmux?&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Run long-running processes that survive disconnection&lt;/li&gt;&#xA;&lt;li&gt;Split terminal into multiple panes&lt;/li&gt;&#xA;&lt;li&gt;Multiple windows in one session&lt;/li&gt;&#xA;&lt;li&gt;Share sessions with others&lt;/li&gt;&#xA;&lt;li&gt;Scripted layouts&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Ubuntu/Debian&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt install tmux&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# macOS&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install tmux&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;sessions&#34;&gt;Sessions&lt;/h2&gt;&#xA;&lt;h3 id=&#34;create-and-manage&#34;&gt;Create and Manage&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Start new session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmux&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Named session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmux new -s mysession&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# List sessions&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmux ls&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Attach to session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmux attach -t mysession&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Kill session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmux kill-session -t mysession&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;detach&#34;&gt;Detach&lt;/h3&gt;&#xA;&lt;p&gt;Inside tmux, press: &lt;code&gt;Ctrl+b d&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Process Management</title>
      <link>/posts/linux-process-management/</link>
      <pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-process-management/</guid>
      <description>&lt;p&gt;Every running program is a process. Understanding how to view, control, and manage processes is essential for Linux administration.&lt;/p&gt;&#xA;&lt;h2 id=&#34;process-basics&#34;&gt;Process Basics&lt;/h2&gt;&#xA;&lt;h3 id=&#34;what-is-a-process&#34;&gt;What is a Process?&lt;/h3&gt;&#xA;&lt;p&gt;A process is a running instance of a program. Each process has:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;PID&lt;/strong&gt;: Process ID (unique identifier)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;PPID&lt;/strong&gt;: Parent Process ID&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;UID/GID&lt;/strong&gt;: User/Group running the process&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;State&lt;/strong&gt;: Running, sleeping, stopped, zombie&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Priority&lt;/strong&gt;: Scheduling priority&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;process-states&#34;&gt;Process States&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;State&lt;/th&gt;&#xA;          &lt;th&gt;Symbol&lt;/th&gt;&#xA;          &lt;th&gt;Description&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Running&lt;/td&gt;&#xA;          &lt;td&gt;R&lt;/td&gt;&#xA;          &lt;td&gt;Currently executing&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Sleeping&lt;/td&gt;&#xA;          &lt;td&gt;S&lt;/td&gt;&#xA;          &lt;td&gt;Waiting for event&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Uninterruptible Sleep&lt;/td&gt;&#xA;          &lt;td&gt;D&lt;/td&gt;&#xA;          &lt;td&gt;Waiting for I/O&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Stopped&lt;/td&gt;&#xA;          &lt;td&gt;T&lt;/td&gt;&#xA;          &lt;td&gt;Suspended&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Zombie&lt;/td&gt;&#xA;          &lt;td&gt;Z&lt;/td&gt;&#xA;          &lt;td&gt;Terminated but not cleaned up&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;viewing-processes&#34;&gt;Viewing Processes&lt;/h2&gt;&#xA;&lt;h3 id=&#34;ps---process-status&#34;&gt;ps - Process Status&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Current user&amp;#39;s processes&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# All processes (standard syntax)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps aux&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# All processes (BSD syntax)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps -ef&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Specific columns&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps -eo pid,ppid,user,%cpu,%mem,cmd&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Tree view&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps auxf&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps -ejH&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# By name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps aux | grep nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pgrep nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;ps-aux-columns&#34;&gt;ps aux Columns&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;USER  PID  %CPU %MEM   VSZ   RSS TTY STAT START TIME COMMAND&#xA;root    1   0.0  0.1 168936 11204 ?   Ss   10:00 0:02 /sbin/init&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Column&lt;/th&gt;&#xA;          &lt;th&gt;Meaning&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;USER&lt;/td&gt;&#xA;          &lt;td&gt;Owner&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;PID&lt;/td&gt;&#xA;          &lt;td&gt;Process ID&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;%CPU&lt;/td&gt;&#xA;          &lt;td&gt;CPU usage&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;%MEM&lt;/td&gt;&#xA;          &lt;td&gt;Memory usage&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;VSZ&lt;/td&gt;&#xA;          &lt;td&gt;Virtual memory (KB)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;RSS&lt;/td&gt;&#xA;          &lt;td&gt;Resident memory (KB)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;TTY&lt;/td&gt;&#xA;          &lt;td&gt;Terminal&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;STAT&lt;/td&gt;&#xA;          &lt;td&gt;State&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;START&lt;/td&gt;&#xA;          &lt;td&gt;Start time&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;TIME&lt;/td&gt;&#xA;          &lt;td&gt;CPU time used&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;COMMAND&lt;/td&gt;&#xA;          &lt;td&gt;Command&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;top---real-time-monitoring&#34;&gt;top - Real-Time Monitoring&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;top&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Key commands in top:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Systemd: Managing Services and the Init System</title>
      <link>/posts/linux-systemd/</link>
      <pubDate>Sun, 04 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-systemd/</guid>
      <description>&lt;p&gt;Systemd is the init system and service manager on most modern Linux distributions. It manages the boot process and system services.&lt;/p&gt;&#xA;&lt;h2 id=&#34;systemd-basics&#34;&gt;Systemd Basics&lt;/h2&gt;&#xA;&lt;h3 id=&#34;what-systemd-manages&#34;&gt;What Systemd Manages&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Services&lt;/strong&gt;: Daemons and background processes&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Mounts&lt;/strong&gt;: Filesystem mounting&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Devices&lt;/strong&gt;: Hardware devices&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Sockets&lt;/strong&gt;: Network and IPC sockets&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Timers&lt;/strong&gt;: Scheduled tasks (cron replacement)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Targets&lt;/strong&gt;: Groups of units (like runlevels)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;unit-files&#34;&gt;Unit Files&lt;/h3&gt;&#xA;&lt;p&gt;Systemd uses &amp;ldquo;unit files&amp;rdquo; to define how to manage resources. Located in:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Path&lt;/th&gt;&#xA;          &lt;th&gt;Purpose&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;/lib/systemd/system/&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Distribution-provided&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;/etc/systemd/system/&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Administrator overrides&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;~/.config/systemd/user/&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;User services&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;managing-services&#34;&gt;Managing Services&lt;/h2&gt;&#xA;&lt;h3 id=&#34;systemctl-basics&#34;&gt;systemctl Basics&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;20&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;21&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;22&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;23&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Start service&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl start nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Stop service&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl stop nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Restart service&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl restart nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Reload configuration (no downtime)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl reload nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Check status&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl status nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Enable at boot&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl enable nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Disable at boot&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl disable nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Enable and start&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl enable --now nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;service-status&#34;&gt;Service Status&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl status nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Output explained:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Shell Scripting Fundamentals for Linux</title>
      <link>/posts/linux-shell-scripting/</link>
      <pubDate>Fri, 02 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-shell-scripting/</guid>
      <description>&lt;p&gt;Shell scripting automates repetitive tasks and ties together Linux tools. Here&amp;rsquo;s how to write effective scripts.&lt;/p&gt;&#xA;&lt;h2 id=&#34;script-basics&#34;&gt;Script Basics&lt;/h2&gt;&#xA;&lt;h3 id=&#34;first-script&#34;&gt;First Script&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# This is a comment&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Make executable&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod +x script.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Run&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./script.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# or&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bash script.sh&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;shebang&#34;&gt;Shebang&lt;/h3&gt;&#xA;&lt;p&gt;The first line tells which interpreter to use:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Performance Tuning and Monitoring</title>
      <link>/posts/linux-performance-tuning/</link>
      <pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate>
      <guid>/posts/linux-performance-tuning/</guid>
      <description>&lt;p&gt;Performance tuning requires understanding bottlenecks and knowing which knobs to turn. This guide covers monitoring, analysis, and optimization.&lt;/p&gt;&#xA;&lt;h2 id=&#34;performance-methodology&#34;&gt;Performance Methodology&lt;/h2&gt;&#xA;&lt;h3 id=&#34;the-use-method&#34;&gt;The USE Method&lt;/h3&gt;&#xA;&lt;p&gt;For each resource, check:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;U&lt;/strong&gt;tilization: How busy is it?&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;S&lt;/strong&gt;aturation: Is work queuing?&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;E&lt;/strong&gt;rrors: Are there failures?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;key-resources&#34;&gt;Key Resources&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Resource&lt;/th&gt;&#xA;          &lt;th&gt;Utilization&lt;/th&gt;&#xA;          &lt;th&gt;Saturation&lt;/th&gt;&#xA;          &lt;th&gt;Errors&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;CPU&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;top&lt;/code&gt;, &lt;code&gt;mpstat&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Load average, runqueue&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;dmesg&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Memory&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;free&lt;/code&gt;, &lt;code&gt;vmstat&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Swapping&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;dmesg&lt;/code&gt;, OOM&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Disk&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;iostat&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Wait queue&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;smartctl&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Network&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;sar -n DEV&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Socket backlog&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ip -s&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;cpu-performance&#34;&gt;CPU Performance&lt;/h2&gt;&#xA;&lt;h3 id=&#34;monitoring-cpu&#34;&gt;Monitoring CPU&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Overall usage&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;top&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;htop&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Per-CPU statistics&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mpstat -P ALL &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Load average&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;uptime&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /proc/loadavg&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 1.25 0.87 0.65 2/245 12345&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 1min 5min 15min running/total last_pid&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# CPU info&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lscpu&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /proc/cpuinfo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;understanding-load-average&#34;&gt;Understanding Load Average&lt;/h3&gt;&#xA;&lt;p&gt;Load average represents average runnable processes:&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
