<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shrijith Venkatramana</title>
    <description>The latest articles on DEV Community by Shrijith Venkatramana (@shrsv).</description>
    <link>https://dev.to/shrsv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1001514%2F17b7d334-44b1-417a-9268-346e6a34988a.jpg</url>
      <title>DEV Community: Shrijith Venkatramana</title>
      <link>https://dev.to/shrsv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shrsv"/>
    <language>en</language>
    <item>
      <title>We Built a Free AI Code Review That Runs on Every Commit</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Sat, 21 Feb 2026 10:23:47 +0000</pubDate>
      <link>https://dev.to/shrsv/we-built-a-free-ai-code-review-that-runs-on-every-commit-ij1</link>
      <guid>https://dev.to/shrsv/we-built-a-free-ai-code-review-that-runs-on-every-commit-ij1</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Moment We Realized Something Was Off
&lt;/h2&gt;

&lt;p&gt;In our team, AI tools like Copilot and Cursor clearly increased velocity. Features moved faster. Refactors felt cheaper. Boilerplate disappeared.&lt;/p&gt;

&lt;p&gt;But careful inspection of code quietly declined.&lt;/p&gt;

&lt;p&gt;AI would generate large diffs. They looked reasonable. They compiled. Tests passed. So they landed.&lt;/p&gt;

&lt;p&gt;Only later would we discover subtle issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A validation check removed.&lt;/li&gt;
&lt;li&gt;A constraint relaxed.&lt;/li&gt;
&lt;li&gt;An edge case dropped.&lt;/li&gt;
&lt;li&gt;An expensive cloud call introduced.&lt;/li&gt;
&lt;li&gt;Sensitive material leaking into logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing dramatic. Just small, silent shifts.&lt;br&gt;&lt;br&gt;
And those are the ones that cost hours in production debugging.&lt;/p&gt;

&lt;p&gt;We had given ourselves a race car.&lt;/p&gt;

&lt;p&gt;We forgot the brakes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why We Didn’t Build Another Dashboard
&lt;/h2&gt;

&lt;p&gt;The obvious solution would’ve been another SaaS review tool or another CI gate.&lt;/p&gt;

&lt;p&gt;I didn’t want that.&lt;/p&gt;

&lt;p&gt;Responsibility in software engineering has a natural anchor point: &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Every editor, every IDE, every AI agent eventually hits Git.&lt;br&gt;&lt;br&gt;
Committing is mandatory. It’s the moment a developer says:&lt;br&gt;&lt;br&gt;
“I stand behind this change.”&lt;/p&gt;

&lt;p&gt;So we built &lt;strong&gt;git-lrc&lt;/strong&gt; to live exactly there.&lt;/p&gt;

&lt;p&gt;It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every staged diff &lt;em&gt;before&lt;/em&gt; it lands.&lt;/p&gt;

&lt;p&gt;When you commit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub-style diff opens in your browser.&lt;/li&gt;
&lt;li&gt;Inline AI comments appear at the exact lines that matter.&lt;/li&gt;
&lt;li&gt;Issues are tagged with severity.&lt;/li&gt;
&lt;li&gt;A high-level summary explains what changed.&lt;/li&gt;
&lt;li&gt;You can copy flagged issues back into your AI agent.&lt;/li&gt;
&lt;li&gt;Lines added/removed per file are shown for quick scope awareness.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No dashboards. No external process.&lt;br&gt;&lt;br&gt;
Just a structural nudge at the right moment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Review, Vouch, or Skip — Your Choice
&lt;/h2&gt;

&lt;p&gt;git-lrc is engineer-centric by design.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Review&lt;/strong&gt; — run AI analysis on the diff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vouch&lt;/strong&gt; — skip AI and explicitly take responsibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skip&lt;/strong&gt; — commit without review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every commit records what happened directly in &lt;code&gt;git log&lt;/code&gt;, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LiveReview Pre-Commit Check: ran (iter:3, coverage:85%)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iter&lt;/code&gt; shows how many review cycles you ran.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;coverage&lt;/code&gt; shows how much of the final diff was AI-reviewed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your team can see exactly which commits were reviewed, vouched, or skipped — without any external reporting tool.&lt;/p&gt;

&lt;p&gt;Review becomes part of authorship, not an afterthought.&lt;/p&gt;
&lt;h2&gt;
  
  
  Designed for AI Workflows
&lt;/h2&gt;

&lt;p&gt;A typical cycle looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate code with your AI agent.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git lrc review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;AI flags issues inline.&lt;/li&gt;
&lt;li&gt;Copy issues back to your agent.&lt;/li&gt;
&lt;li&gt;Fix.&lt;/li&gt;
&lt;li&gt;Review again.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git lrc review --vouch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Commit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each review is tracked as an iteration.&lt;br&gt;&lt;br&gt;
You move fast — but deliberately.&lt;/p&gt;
&lt;h2&gt;
  
  
  60 Seconds to Set Up. Completely Free.
&lt;/h2&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://hexmos.com/lrc-install.sh | &lt;span class="nb"&gt;sudo &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git lrc setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You bring your own &lt;strong&gt;Gemini API key&lt;/strong&gt; (free tier).&lt;br&gt;&lt;br&gt;
There’s no billing layer. Unlimited reviews.&lt;/p&gt;

&lt;p&gt;Only the staged diff is analyzed.&lt;br&gt;&lt;br&gt;
No full repository upload.&lt;br&gt;&lt;br&gt;
Diffs are not stored after review.&lt;/p&gt;

&lt;p&gt;The mission is simple:&lt;/p&gt;

&lt;p&gt;Make AI code review engineer-centric, free, and accessible to developers everywhere.&lt;/p&gt;

&lt;p&gt;The more devDevelopers review AI-generated code early, the fewer subtle bugs make it to production&lt;/p&gt;

&lt;p&gt;Make AI code review engineer-centric, free, and accessible to developers everywhere.&lt;/p&gt;

&lt;p&gt;AI-assisted coding is becoming the default.&lt;/p&gt;

&lt;p&gt;The real question isn’t whether we use AI.&lt;br&gt;&lt;br&gt;
It’s whether we stay responsible while using it.&lt;/p&gt;

&lt;p&gt;If you care about shipping fast without silently degrading quality, I’d appreciate your support.&lt;/p&gt;

&lt;p&gt;👉 Upvote git-lrc on Product Hunt:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.producthunt.com/products/git-lrc" rel="noopener noreferrer"&gt;https://www.producthunt.com/products/git-lrc&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The more developers review AI-generated code early, the fewer subtle bugs make it to production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The future belongs to those who can refute AI, not just generate with AI</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Thu, 19 Feb 2026 13:36:54 +0000</pubDate>
      <link>https://dev.to/shrsv/the-future-belongs-to-those-who-can-refute-ai-not-just-generate-with-ai-28i0</link>
      <guid>https://dev.to/shrsv/the-future-belongs-to-those-who-can-refute-ai-not-just-generate-with-ai-28i0</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;The assumption in software engineering circles has been that if AI lets us write code faster, we will build more things and move faster.

&lt;p&gt;That assumption misses a step.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Writing code is not the same as integrating it, maintaining it, or trusting it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We are starting to discover that verification does not scale the way generation does.&lt;/p&gt;

&lt;p&gt;I argue that the engineer who thrives in this environment will &lt;em&gt;not&lt;/em&gt; be the one who can prompt the largest code output. It will be the one who can look at what comes out and reliably decide what survives.&lt;/p&gt;

&lt;p&gt;This post is about &lt;em&gt;why that skill — of refutation — is about to become central,&lt;/em&gt; and what it means for how we build software.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Volume is no longer a signal of value.
&lt;/h2&gt;

&lt;p&gt;We are in the middle of a real GenAI explosion.&lt;/p&gt;

&lt;p&gt;Code, images, video, documents — all of it can now be generated at a cost that is rapidly approaching zero compared to the historical human-labor baseline.&lt;/p&gt;

&lt;p&gt;In software engineering especially, the ability to write a lot of code has traditionally been associated with productivity and even creativity.&lt;/p&gt;

&lt;p&gt;That association is now breaking down.&lt;/p&gt;

&lt;p&gt;We can generate more than ever before, faster than ever before.&lt;/p&gt;

&lt;p&gt;Volume by itself has lost meaning.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Knowledge is what survives attack.
&lt;/h2&gt;

&lt;p&gt;To understand what is changing, it helps to step back and borrow from epistemology.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Epistemology is the branch of philosophy that separates knowledge from what is not knowledge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Merely having experience with something is not knowledge.&lt;/p&gt;

&lt;p&gt;Repeating what supposed authorities have propounded is not knowledge.&lt;/p&gt;

&lt;p&gt;Making statements based on experience is not knowledge either.&lt;/p&gt;

&lt;p&gt;Statements become candidates for knowledge only when they are internally consistent, publicly testable, and able to survive adversarial scrutiny.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0x1afplbns0i6ki1109.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0x1afplbns0i6ki1109.png" alt="Karl Popper"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Value is revealed under attack, not in the design lab
&lt;/h2&gt;

&lt;p&gt;A useful analogy is military hardware.&lt;/p&gt;

&lt;p&gt;The worth of a battle tank is not established in the design lab or by marketing brochures.&lt;/p&gt;

&lt;p&gt;Its worth is demonstrated by how it withstands attack in actual battle. &lt;em&gt;Until it has faced stress, resistance, and hostile conditions, we cannot make serious claims about its efficacy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The same applies to ideas, designs, and code. Their value is revealed under attack.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. The source of an idea does not matter; only its survival matters.
&lt;/h2&gt;

&lt;p&gt;Karl Popper made this explicit: the source cannot be trusted.&lt;/p&gt;

&lt;p&gt;It does not matter whether a claim comes from a famous scientist, a senior engineer, or a large language model.&lt;/p&gt;

&lt;p&gt;What matters is whether the claim survives attempts to falsify it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge grows through conjecture and refutation, not through confident assertion.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Popper was writing about the demarcation of science from non-science, but the pattern applies more broadly: without the possibility of being shown wrong, we cannot claim to have learned anything.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. GenAI is a conjecture engine; everything it produces is provisional.
&lt;/h2&gt;

&lt;p&gt;GenAI, at its core, is a conjecture engine.&lt;/p&gt;

&lt;p&gt;Every piece of generated code is a proposed theory about how a system should behave.&lt;/p&gt;

&lt;p&gt;Every generated explanation is a proposed interpretation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All of it must be treated as provisional.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Everything AI generates should be considered a proposed theory and then subjected to severe testing and criticism to see if it survives.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. We already had systems for adversarial scrutiny (CI/CD, code review).
&lt;/h2&gt;

&lt;p&gt;This was already true in the pre-AI world.&lt;/p&gt;

&lt;p&gt;That is why we invented code review, linters, and continuous integration in the first place. We recognized that humans make mistakes, that first drafts are often wrong, and that structured criticism improves outcomes.&lt;/p&gt;

&lt;p&gt;CI/CD pipelines, unit tests, and integration tests are all mechanisms for subjecting code to adversarial scrutiny.&lt;/p&gt;

&lt;p&gt;In that sense, applied Popperian epistemology has been embedded in our workflows for years.&lt;/p&gt;
&lt;h2&gt;
  
  
  7. Historical software growth: about 20% per year.
&lt;/h2&gt;

&lt;p&gt;What changes now is scale.&lt;/p&gt;

&lt;p&gt;In 2016, Professor Hatton and his team published &lt;a href="https://onlinelibrary.wiley.com/doi/10.1002/smr.1847" rel="noopener noreferrer"&gt;The Long-Term Growth Rate of Evolving Software.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They studied how software codebases grew over time, long before GenAI was in the picture.&lt;/p&gt;

&lt;p&gt;Their finding was strikingly consistent: historically, software projects grew at about a 20% compound annual growth rate (CAGR).&lt;/p&gt;

&lt;p&gt;At that rate, a codebase roughly doubles in size in about four years.&lt;/p&gt;

&lt;p&gt;It is important to note that this paper describes how codebases actually grew, not a theoretical maximum. It is a historical baseline, not a physical law.&lt;/p&gt;
&lt;h2&gt;
  
  
  8. Monster codebases are a plausible outcome of AI-driven productivity.
&lt;/h2&gt;

&lt;p&gt;Now consider what happens if AI meaningfully boosts developer productivity.&lt;/p&gt;

&lt;p&gt;If productivity doubles and CAGR moves toward 40%, doubling time shrinks to roughly two years.&lt;/p&gt;

&lt;p&gt;If productivity increases fivefold and we approach 100% CAGR, a codebase doubles every year.&lt;/p&gt;

&lt;p&gt;Over a decade, that compounding is explosive. A 5× productivity boost sustained over ten years could translate into a roughly 165× increase in code volume.&lt;/p&gt;

&lt;p&gt;A medium-sized 100,000 LOC codebase could plausibly turn into 100 million LOC.&lt;/p&gt;

&lt;p&gt;For context, the Linux kernel reached around 40 million LOC after three decades of evolution.&lt;/p&gt;

&lt;p&gt;We are potentially heading toward “monster codebases.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7r8uyvvxhy8jltr2nm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7r8uyvvxhy8jltr2nm5.png" alt="Monster Codebases"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  9. But isn’t growth bounded by complexity? Yes, but significant growth is still likely
&lt;/h2&gt;

&lt;p&gt;This projection invites immediate objections.&lt;/p&gt;

&lt;p&gt;First, the 20% CAGR comes from a pre-LLM world; using it to predict a post-LLM world is logically tension-ridden.&lt;/p&gt;

&lt;p&gt;The historical trend gives us a baseline against which to measure disruption.&lt;/p&gt;

&lt;p&gt;If the trend holds, nothing changes.&lt;/p&gt;

&lt;p&gt;If it breaks, we need to understand the new environment.&lt;/p&gt;

&lt;p&gt;Second, software growth is bounded by complexity, not just typing speed.&lt;/p&gt;

&lt;p&gt;A 100 million LOC codebase might be unbuildable or unmaintainable regardless of how fast we can write code, because integration complexity grows faster than linearly.&lt;/p&gt;

&lt;p&gt;If we generate code faster than we can manage its integration complexity, we build systems that collapse under their own weight.&lt;/p&gt;

&lt;p&gt;The question is whether our verification systems scale with it.&lt;/p&gt;
&lt;h2&gt;
  
  
  10. The old equilibrium between writing and reviewing code breaks at scale.
&lt;/h2&gt;

&lt;p&gt;Historically, review processes could grow alongside codebases.&lt;/p&gt;

&lt;p&gt;If code grew 20% per year, human review capacity could roughly keep pace.&lt;/p&gt;

&lt;p&gt;But if code volume grows by multiples, not percentages, the old equilibrium breaks.&lt;/p&gt;

&lt;p&gt;We move from incremental growth to bulk production of code.&lt;/p&gt;

&lt;p&gt;How will refutation grow with generation?&lt;/p&gt;
&lt;h2&gt;
  
  
  11. AI must help with verification, or human review collapses.
&lt;/h2&gt;

&lt;p&gt;At that point, attention becomes the scarce resource.&lt;/p&gt;

&lt;p&gt;As generated output increases, value shifts from production to selection.&lt;/p&gt;

&lt;p&gt;The key problem becomes: how do we direct limited human attention to the most important risks inside an ocean of machine-generated diffs?&lt;/p&gt;

&lt;p&gt;How do we build higher-level representations that compress massive change into manageable insight?&lt;/p&gt;

&lt;p&gt;There is no realistic path forward without using AI to verify as well.&lt;/p&gt;

&lt;p&gt;Human-only review cannot keep up with machine-scale generation.&lt;/p&gt;

&lt;p&gt;AI must help draw attention to useful things, highlight potential constraint violations, detect behavioral drift, and reduce the burden of review.&lt;/p&gt;

&lt;p&gt;Verification must become partially automated, or it simply collapses.&lt;/p&gt;
&lt;h2&gt;
  
  
  12. But if AI is flawed, can AI review be trusted? (The infinite regress problem).
&lt;/h2&gt;

&lt;p&gt;This is where the most obvious objection arises: if the AI that generates code is flawed and produces hallucinations, why would an AI that reviews code be any less flawed?&lt;/p&gt;

&lt;p&gt;Would this not simply compound errors rather than catch them? This is sometimes called the infinite regress problem — if we need an AI to check the AI, who checks the checker?&lt;/p&gt;
&lt;h2&gt;
  
  
  13. Specialized review AI is different from general generation AI.
&lt;/h2&gt;

&lt;p&gt;The answer lies in specialization.&lt;/p&gt;

&lt;p&gt;A review AI does not need to be a general intelligence.&lt;/p&gt;

&lt;p&gt;It needs to be a focused tool for checking specific properties: type correctness, conformance to project style, violation of defined architectural boundaries, or behavioral drift captured by property-based tests.&lt;/p&gt;

&lt;p&gt;The model used for review can be different from the one used for generation — smaller, more conservative.&lt;/p&gt;

&lt;p&gt;Review AI is not asked to have an opinion about whether code is “good.”&lt;/p&gt;

&lt;p&gt;It is asked to surface anomalies to a human.&lt;/p&gt;

&lt;p&gt;It acts as a tireless, fast, but ultimately fallible junior reviewer whose job is to flag anything unusual and let the senior engineer make the final call.&lt;/p&gt;

&lt;p&gt;The goal is not to eliminate human judgment, but to focus it.&lt;/p&gt;
&lt;h2&gt;
  
  
  14. Guardrails belong in verification, not just generation.
&lt;/h2&gt;

&lt;p&gt;This is also where guardrails belong.&lt;/p&gt;

&lt;p&gt;Guardrails should primarily sit on the verification layer, not the generation layer.&lt;/p&gt;

&lt;p&gt;Trying to constrain generation alone is like trying to prevent all bad tank designs at the drawing board.&lt;/p&gt;

&lt;p&gt;A more robust approach is to subject every design to rigorous criticism and stress testing.&lt;/p&gt;

&lt;p&gt;Instead of focusing on censoring models as the main control mechanism, we should upgrade our verification methods.&lt;/p&gt;

&lt;p&gt;There is room for debate here: some harms occur at the moment of generation, not execution, and generation-layer guardrails address those.&lt;/p&gt;

&lt;p&gt;But for engineering reliability, verification is where the leverage lies.&lt;/p&gt;
&lt;h2&gt;
  
  
  15. Perhaps we’ll write less, more leveraged code. But verification shifts, it doesn’t disappear.
&lt;/h2&gt;

&lt;p&gt;A different kind of objection comes from economics.&lt;/p&gt;

&lt;p&gt;Perhaps the future is not monster codebases but minimal, highly leveraged ones.&lt;/p&gt;

&lt;p&gt;If code becomes cheap, the incentive to write efficient, reusable abstractions increases.&lt;/p&gt;

&lt;p&gt;Why generate a thousand lines of boilerplate when a ten-line configuration file powered by AI does the same thing?&lt;/p&gt;

&lt;p&gt;This is possible.&lt;/p&gt;

&lt;p&gt;But even minimal codebases require verification of their minimal parts, and the leverage increases the blast radius of any mistake.&lt;/p&gt;

&lt;p&gt;Whether code volume expands or contracts, the verification load shifts rather than disappears.&lt;/p&gt;

&lt;p&gt;The scarce resource remains human attention directed at the right places.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If GenAI scales conjecture, ReviewAI must scale refutation.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  16. Market saturation might limit growth, but problem space is far from exhausted.
&lt;/h2&gt;

&lt;p&gt;Another objection is that growth in code volume will eventually hit market saturation.&lt;/p&gt;

&lt;p&gt;We do not have an infinite number of meaningful problems to solve. After a point, generating more code just creates noise and technical debt.&lt;/p&gt;

&lt;p&gt;But this assumes that the problem surface is close to saturated. It is not.&lt;/p&gt;

&lt;p&gt;Consider countries like India. Large-scale infrastructure gaps, pollution management, logistics inefficiencies, healthcare access, education quality, urban planning, agricultural optimization — these are not marginal problems.&lt;/p&gt;

&lt;p&gt;They are system-level challenges that require coordination, monitoring, simulation, automation, and optimization at scale. All of these increasingly rely on software.&lt;/p&gt;

&lt;p&gt;Even in developed economies, software penetration into physical systems is still incomplete: energy grids, water systems, public transport, manufacturing, climate modeling, robotics, biotech.&lt;/p&gt;

&lt;p&gt;As capability expands, software does not merely fill existing markets; it enables new domains of intervention.&lt;/p&gt;

&lt;p&gt;Historically, when production capacity increases, demand tends to expand into areas previously considered infeasible.&lt;/p&gt;

&lt;p&gt;The limiting factor has rarely been a shortage of problems. It has been cost and coordination.&lt;/p&gt;
&lt;h2&gt;
  
  
  17. Engineering must adapt, because norms evolve too slowly.
&lt;/h2&gt;

&lt;p&gt;Engineering as a field needs to internalize this shift.&lt;/p&gt;

&lt;p&gt;The discipline has always depended on separating what works from what merely appears to work.&lt;/p&gt;

&lt;p&gt;Having experience building something does not make it reliable.&lt;/p&gt;

&lt;p&gt;Having it survive adversarial testing does.&lt;/p&gt;

&lt;p&gt;With code volume potentially compounding at unprecedented rates, we do not have the luxury of slowly evolving norms.&lt;/p&gt;

&lt;p&gt;We need accessible, cost-effective verification tools that integrate directly into development workflows.&lt;/p&gt;
&lt;h2&gt;
  
  
  18. A concrete direction: automated review on every git commit.
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://hexmos.com/livereview/git-lrc/" rel="noopener noreferrer"&gt;my own work on AI-assisted code review&lt;/a&gt;, I have been building tooling that triggers review automatically when diffs are committed to git repositories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxct9d4ivrgdk2b6075ut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxct9d4ivrgdk2b6075ut.png" alt="git-lrc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is straightforward: treat every change as a hypothesis and subject it to systematic attack.&lt;/p&gt;

&lt;p&gt;In a sense, this is applied Popperian epistemology embedded in CI/CD. The goal is not to slow down generation, but to make criticism abundant.&lt;/p&gt;

&lt;p&gt;I do not claim this solves every problem.&lt;/p&gt;

&lt;p&gt;The tools are early, the approaches are experimental, and the infinite regress concern is real.&lt;/p&gt;

&lt;p&gt;But it’s time we started taking our ReviewAI stack more seriously.&lt;/p&gt;
&lt;h2&gt;
  
  
  19. The future belongs to those who can refute, not just generate.
&lt;/h2&gt;

&lt;p&gt;GenAI has made conjecture cheap.&lt;/p&gt;

&lt;p&gt;The risks of compounding error are real.&lt;/p&gt;

&lt;p&gt;If we do not make refutation equally powerful and widely available, we risk drowning in our own output.&lt;/p&gt;

&lt;p&gt;The future of engineering in the AI era will not be decided by how much we can generate, but by how rigorously we decide what survives.&lt;/p&gt;

&lt;p&gt;And that decision of what survives, in the end, remains a human responsibility.&lt;/p&gt;

&lt;p&gt;And I for one hope that Refutation as an idea gets taken as seriously as the idea of generation in the industry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>career</category>
      <category>ai</category>
      <category>discuss</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI Is Stress-Testing Software Engineering as a Profession</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Fri, 06 Feb 2026 15:20:06 +0000</pubDate>
      <link>https://dev.to/shrsv/ai-is-stress-testing-software-engineering-as-a-profession-21b6</link>
      <guid>https://dev.to/shrsv/ai-is-stress-testing-software-engineering-as-a-profession-21b6</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;The arrival of large-scale AI systems has triggered two predictably disappointing reactions among a large swath of software engineers: &lt;strong&gt;hype and fear&lt;/strong&gt;.

&lt;p&gt;One group greets AI with unrestrained excitement, extrapolating demos into destiny. This position is usually held by the less experienced or by those with commercial interests tied to the narrative&lt;/p&gt;

&lt;p&gt;Another treats it as an existential threat, assuming wholesale displacement and professional irrelevance. This reaction often comes from more experienced engineers who have grown comfortable in a particular context and are primarily focused on protecting their existing paycheck.&lt;/p&gt;

&lt;p&gt;Both responses, in my view, are mistakes. They share a common flaw: &lt;em&gt;neither is a professional response.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Professions are defined not by the tools they use, but by the responsibilities they accept.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Medicine as a field of practice did not go extinct when diagnostic machines improved.&lt;/p&gt;

&lt;p&gt;Civil engineering did not dissolve when materials science advanced.&lt;/p&gt;

&lt;p&gt;In each case, the profession adapted by elevating standards of judgment, verification, and accountability.&lt;/p&gt;

&lt;p&gt;Software engineering is now being asked to do the same.&lt;/p&gt;

&lt;p&gt;This moment is not about defending status or losing one’s bearings due to excessive exuberance. &lt;strong&gt;AI is an opportunity for the field of Software Engineering to grow up.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Failure of Hype and Fear
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Hype is a failure of epistemic, mental and professional discipline.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It treats impressive behavior under controlled conditions as proof of general reliability.&lt;/p&gt;

&lt;p&gt;It confuses surface fluency with understanding and mistakenly assumes that systems somehow work out OK on their own.&lt;/p&gt;

&lt;p&gt;Engineers who have never owned production systems are especially vulnerable to this error, because they have not yet internalized how often “working” systems fail in unexpected ways.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fear is a different failure, but a failure nonetheless.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It assumes that because a tool can perform a task, it can absorb responsibility for that task.&lt;/p&gt;

&lt;p&gt;This is a category error.&lt;/p&gt;

&lt;p&gt;Tools do not bear accountability. People do.&lt;/p&gt;

&lt;p&gt;When engineers retreat into narratives of irrelevance under the banner of realism - they are in practice abandoning professional duty.&lt;/p&gt;

&lt;p&gt;Neither posture helps society.&lt;/p&gt;

&lt;p&gt;Neither deserves trust.&lt;/p&gt;
&lt;h2&gt;
  
  
  What a Professional Response Looks Like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A professional response begins with responsibility.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Engineers remain responsible for the behavior of systems they design, deploy, and maintain, regardless of how much automation is involved.&lt;/p&gt;

&lt;p&gt;“The model did it” is not an explanation; it is an abdication.&lt;/p&gt;

&lt;p&gt;If a system cannot be explained, evaluated, or bounded, it should not be deployed in contexts where failure matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Professionals are also defined by epistemic discipline.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They distinguish what is known from what is uncertain, what has been validated from what merely appears to work.&lt;/p&gt;

&lt;p&gt;They resist both excitement and panic because both distort judgment.&lt;/p&gt;

&lt;p&gt;Calm assessment under uncertainty is not optional; it is the core professional skill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verification becomes more important, not less.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As generative systems make production cheaper, review, checking, auditing, and adversarial testing become the scarce skills.&lt;/p&gt;

&lt;p&gt;Creation can be automated. Validation cannot be outsourced to systems that do not understand consequences.&lt;/p&gt;

&lt;p&gt;Only those who understands the dynamics and history of a system end-to-end can vouch for it competently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/LiveReview" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fggpy9ixpjv3u0xeanm91.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authority, when exercised, must be tied to truth rather than status.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Professionals do not claim legitimacy by insisting on uniqueness, nor do they forfeit it by denying their value.&lt;/p&gt;

&lt;p&gt;They earn authority by explaining limits clearly, correcting errors publicly, and refusing to overstate confidence.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Credibility comes from accuracy, not bravado.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finally, a professional response is system-level.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Engineers must reason about sociotechnical systems: incentives, organizations, feedback loops, and long-term maintenance.&lt;/p&gt;

&lt;p&gt;They ask uncomfortable questions, such as who pays when the system fails and how errors propagate beyond the technical boundary.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is the difference between building artifacts and practicing engineering.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Training That Produces Professionals
&lt;/h2&gt;

&lt;p&gt;Professional judgment does not emerge from tool fluency or short courses alone.&lt;/p&gt;

&lt;p&gt;It is cultivated through specific forms of training and experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first is production responsibility.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is no substitute for owning systems that can fail, being paged when they do, and living with the consequences of design decisions.&lt;/p&gt;

&lt;p&gt;This experience teaches restraint, humility, and realism.&lt;/p&gt;

&lt;p&gt;It is why experienced engineers react differently to AI hype than those who have only shipped prototypes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second is rigorous reasoning.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Training in logic, probability, statistics, and failure analysis and many other topics, including the liberal arts - produces a human being capable of taking on real responsibility.&lt;/p&gt;

&lt;p&gt;Professionals must train their thought, emotion, speech and actions to serve with competence.&lt;/p&gt;

&lt;p&gt;Professionals ask what assumptions are being made, how brittle those assumptions are, and what evidence would falsify their beliefs.&lt;/p&gt;

&lt;p&gt;Without this discipline, AI becomes a baseless confidence amplifier rather than a tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third, writing must be treated as a core technical skill.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design documents, postmortems, risk analyses, and model evaluations are not administrative overhead; they are how thinking is made inspectable.&lt;/p&gt;

&lt;p&gt;Writing forces clarity and exposes gaps in understanding.&lt;/p&gt;

&lt;p&gt;Managing AI systems is largely a writing problem: constraints, evaluations, prompts, and decision rationales are textual artifacts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fourth, professionals study failure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Engineering history is rich with disasters caused not by a lack of intelligence, but by overconfidence, normalized deviance, and misaligned incentives.&lt;/p&gt;

&lt;p&gt;These patterns repeat.&lt;/p&gt;

&lt;p&gt;Engineers who do not study them are condemned to reenact them with more powerful tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fifth, training must include organizational, political and human factors.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most large failures are not purely technical.&lt;/p&gt;

&lt;p&gt;They arise from communication breakdowns, incentive misalignment, mismanagement of various resources, and diffusion of responsibility.&lt;/p&gt;

&lt;p&gt;Engineers who ignore these factors are operating with an awfully inaccurate model of reality.&lt;/p&gt;

&lt;p&gt;Finally, professional formation requires an ethos rather than a mere “We’re special” identity.&lt;/p&gt;

&lt;p&gt;The question is not whether engineers are special.&lt;/p&gt;

&lt;p&gt;The question is whether they are worthy of trust in important and complex matters at hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trust is earned through clarity, restraint, and accountability over time, not through novelty or self-assertion.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Task Before Us
&lt;/h2&gt;

&lt;p&gt;AI does not eliminate software engineering as a profession, although it demands introspection, reforms, evolution in it.&lt;/p&gt;

&lt;p&gt;It merely removes the comfort of immaturity.&lt;/p&gt;

&lt;p&gt;It makes excuses harder to sustain and sloppy thinking more visible.&lt;/p&gt;

&lt;p&gt;In exchange, it raises the ceiling for those willing to accept responsibility and exercise judgment.&lt;/p&gt;

&lt;p&gt;Software will still be required in the world - but the way it gets created and handled may change drastically in the upcoming months and years.&lt;/p&gt;

&lt;p&gt;Growing up will not feel glamorous. It will involve less excitement, less fear, more verification, and more uncelebrated work.&lt;/p&gt;

&lt;p&gt;But that is the price of being a profession rather than a trade, and of being trusted rather than merely used. A “coder” is a tradesman (output-focused). An “engineer” is a professional (outcome-focused, risk-bearing). AI may automate the trade, but it stresses the profession.&lt;/p&gt;

&lt;p&gt;This is the test. How software engineering responds will determine whether it matures— or forfeits its claim to authority altogether.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Story of a TCP Packet: An Intuitive Entrypoint To Linux Networking</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Sun, 26 Oct 2025 16:00:32 +0000</pubDate>
      <link>https://dev.to/shrsv/story-of-a-tcp-packet-an-intuitive-entrypoint-to-linux-networking-fj6</link>
      <guid>https://dev.to/shrsv/story-of-a-tcp-packet-an-intuitive-entrypoint-to-linux-networking-fj6</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ever wondered what &lt;code&gt;eth0&lt;/code&gt;, &lt;code&gt;iptables&lt;/code&gt;, &lt;code&gt;nat&lt;/code&gt;, or &lt;code&gt;FORWARD&lt;/code&gt; actually mean in Linux networking? As engineers, we use these terms, but these terms—interfaces, iptables tables and chains, the networking stack—often feel like a black box. What are interfaces, are they hardware or software? Do they always need an IP? What’s the deal with iptables’ tables versus chains? How does a packet even flow through all this?&lt;/p&gt;

&lt;p&gt;This post follows a TCP packet from your browser to a server running nginx, into a Docker container with a Python app, and back. We’ll use an analogy to ease in, a real-world example for context, plain English to clarify, and technical details to satisfy your curiosity. By the end, you’ll understand how Linux networking fits together and why it matters for debugging and building systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Building Analogy: Interfaces as Doors, iptables as Gatekeepers
&lt;/h2&gt;

&lt;p&gt;Picture your server’s network as a busy office building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interfaces&lt;/strong&gt; are doors or hallways. The front entrance (&lt;code&gt;eth0&lt;/code&gt;) welcomes external packets, while internal paths (&lt;code&gt;docker0&lt;/code&gt;, &lt;code&gt;lo&lt;/code&gt;) connect departments. Some doors are physical (like Ethernet ports); others are virtual (software-only).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iptables&lt;/strong&gt; is the security team, with rulebooks (&lt;strong&gt;tables&lt;/strong&gt;) for different tasks—&lt;code&gt;filter&lt;/code&gt; for blocking or allowing, &lt;code&gt;nat&lt;/code&gt; for rewriting addresses. Each rulebook has checkpoints (&lt;strong&gt;chains&lt;/strong&gt;) like reception desks or mailrooms.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;networking stack&lt;/strong&gt; is the building’s delivery system, ensuring letters (packets) reach the right desk through doors and guards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From outside, it’s just sending a letter and getting a reply. Inside, a complex system makes it happen.&lt;/p&gt;

&lt;p&gt;This shows interfaces can be hardware or software, and not all need IPs—some just pass traffic. iptables handles both security and routing (and property modification/mangling, but that's less important for now), and the stack ties it all together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup: From Browser to Dockerized Python App
&lt;/h2&gt;

&lt;p&gt;Here, we will get a high level view of an interaction - which will form the basis of the rest of the post.&lt;/p&gt;

&lt;p&gt;Imagine you visit &lt;code&gt;https://example.com&lt;/code&gt;. Here’s the server setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;nginx&lt;/strong&gt; listens on the server’s public IP &lt;code&gt;203.0.113.10:443&lt;/code&gt; via interface &lt;code&gt;eth0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;nginx proxies requests to a Python app inside a Docker container at &lt;code&gt;172.17.0.2:8000&lt;/code&gt;, connected through a bridge interface &lt;code&gt;docker0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The packet’s journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser → Internet → Server (&lt;code&gt;eth0&lt;/code&gt;, nginx) → &lt;code&gt;docker0&lt;/code&gt; → Container → Python app → Back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This mirrors real-world web app setups. Let’s break it down in plain English from a slighly different angle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plain English: How Packets Enter and Move
&lt;/h2&gt;

&lt;p&gt;When your browser sends a request, the packet arrives at &lt;code&gt;eth0&lt;/code&gt;, a &lt;strong&gt;network interface&lt;/strong&gt;. Interfaces are where packets enter or leave. Some are tied to physical hardware (like an Ethernet card for &lt;code&gt;eth0&lt;/code&gt;), while others, like &lt;code&gt;docker0&lt;/code&gt; or &lt;code&gt;lo&lt;/code&gt; (loopback), are software-based, existing only in the kernel. &lt;strong&gt;Not every interface needs an IP&lt;/strong&gt;— althoug in practice bridges like &lt;code&gt;docker0&lt;/code&gt; often have one and help with forward packets from the server to the containers and back (act as gateways).&lt;/p&gt;

&lt;p&gt;The kernel decides: deliver locally (to nginx on port 443) or forward (to a container)? Before that, &lt;strong&gt;iptables&lt;/strong&gt; steps in. It’s the kernel’s tool for managing packets, handling both &lt;strong&gt;security&lt;/strong&gt; (via the &lt;code&gt;filter&lt;/code&gt; table to allow/deny) and &lt;strong&gt;routing&lt;/strong&gt; (via the &lt;code&gt;nat&lt;/code&gt; table to rewrite addresses). Tables are the big categories; &lt;strong&gt;chains&lt;/strong&gt; are specific checkpoints within them, like &lt;code&gt;INPUT&lt;/code&gt; for local delivery or &lt;code&gt;FORWARD&lt;/code&gt; for routing. Each chain holds rules, like “allow TCP port 443.”&lt;/p&gt;

&lt;p&gt;To see interfaces on your system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# List network interfaces and IPs&lt;/span&gt;
ip addr show
&lt;span class="c"&gt;# Example output (shortened):&lt;/span&gt;
&lt;span class="c"&gt;# 1: lo: &amp;lt;LOOPBACK&amp;gt; inet 127.0.0.1/8&lt;/span&gt;
&lt;span class="c"&gt;# 2: eth0: &amp;lt;BROADCAST&amp;gt; inet 203.0.113.10/24&lt;/span&gt;
&lt;span class="c"&gt;# 3: docker0: &amp;lt;BROADCAST&amp;gt; inet 172.17.0.1/16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  iptables Explained: Tables, Chains, and Their Roles
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;iptables&lt;/strong&gt; is the kernel’s packet-processing engine, controlling both security and routing, among other things. &lt;strong&gt;Tables&lt;/strong&gt; are the top-level categories, each with a purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;filter&lt;/code&gt;: Decides to accept or drop packets (security).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nat&lt;/code&gt;: Rewrites source/destination addresses (routing).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mangle&lt;/code&gt;: Modifies packet headers (less common).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Chains&lt;/strong&gt; are checkpoints within tables, like steps in a process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PREROUTING&lt;/code&gt;: First stop for incoming packets, before routing decisions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;INPUT&lt;/code&gt;: For packets destined locally (e.g., to nginx).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FORWARD&lt;/code&gt;: For packets passing through to another destination (e.g., container).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OUTPUT&lt;/code&gt;: For packets leaving the host.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POSTROUTING&lt;/code&gt;: Final step before packets exit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tables are bigger&lt;/strong&gt; than chains—each table contains multiple chains, and chains hold specific rules, like “accept TCP to port 443.”&lt;/p&gt;

&lt;p&gt;Here’s the structure:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Table&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Groups tasks&lt;/td&gt;
&lt;td&gt;filter (security), nat (routing)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Checkpoint in table&lt;/td&gt;
&lt;td&gt;PREROUTING, INPUT, FORWARD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rule&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Action to take&lt;/td&gt;
&lt;td&gt;Accept port 443, rewrite to 172.17.0.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To add a rule allowing HTTPS:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Add INPUT rule for HTTPS (run as root)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="c"&gt;# No output; verify with:&lt;/span&gt;
&lt;span class="c"&gt;# iptables -L INPUT -v -n&lt;/span&gt;
&lt;span class="c"&gt;# Example: Chain INPUT ... ACCEPT tcp dpt:443&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note that we only reference the &lt;code&gt;INPUT&lt;/code&gt; chain here; the table is implicit. The default table is &lt;code&gt;filter&lt;/code&gt;, so the rule above is shorthand for:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; filter &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 443 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For iptables details, see &lt;a href="https://netfilter.org/documentation/HOWTO/packet-filtering-HOWTO.html" rel="noopener noreferrer"&gt;netfilter documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Packet Hits eth0 and PREROUTING
&lt;/h2&gt;

&lt;p&gt;The packet arrives at &lt;code&gt;eth0&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source: &lt;code&gt;192.168.1.10:50500&lt;/code&gt; (browser)&lt;/li&gt;
&lt;li&gt;Destination: &lt;code&gt;203.0.113.10:443&lt;/code&gt; (server)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The kernel sees the destination IP matches &lt;code&gt;eth0&lt;/code&gt; (local delivery).&lt;/p&gt;

&lt;p&gt;First stop: &lt;code&gt;nat:PREROUTING&lt;/code&gt; for potential &lt;strong&gt;Destination NAT (DNAT)&lt;/strong&gt;, rewriting the destination. Here, nginx is on the host, so no rewrite occurs. In Docker setups with &lt;code&gt;-p 443:8000&lt;/code&gt;, DNAT would change the destination to the container’s IP.&lt;/p&gt;

&lt;p&gt;Capture the packet:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Capture HTTPS traffic on eth0 (run as root)&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 tcp port 443 &lt;span class="nt"&gt;-c&lt;/span&gt; 1 &lt;span class="nt"&gt;-nn&lt;/span&gt;
&lt;span class="c"&gt;# Example: IP 192.168.1.10.50500 &amp;gt; 203.0.113.10.443: Flags [S]...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 2: filter:INPUT Delivers to nginx
&lt;/h2&gt;

&lt;p&gt;Next, the &lt;code&gt;filter:INPUT&lt;/code&gt; chain checks if the packet can reach nginx. A rule like above (&lt;code&gt;--dport 443 -j ACCEPT&lt;/code&gt;) allows it. This is also where tools like &lt;code&gt;ufw&lt;/code&gt; (Uncomplicated Firewall) add their rules—&lt;code&gt;ufw&lt;/code&gt; is a user-friendly frontend for &lt;code&gt;iptables&lt;/code&gt; that primarily manages the &lt;code&gt;filter&lt;/code&gt; table to block or allow traffic.&lt;/p&gt;

&lt;p&gt;nginx processes the request and opens a new connection to the container:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source: &lt;code&gt;172.17.0.1:random&lt;/code&gt; (&lt;code&gt;docker0&lt;/code&gt; on host)&lt;/li&gt;
&lt;li&gt;Destination: &lt;code&gt;172.17.0.2:8000&lt;/code&gt; (container)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;iptables acts before apps&lt;/strong&gt;—it filters or rewrites packets before nginx sees them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Routing Through docker0 to the Container
&lt;/h2&gt;

&lt;p&gt;The kernel routes the new packet via &lt;code&gt;docker0&lt;/code&gt;, a &lt;strong&gt;software bridge&lt;/strong&gt; interface (no IP, just forwards). Containers use &lt;strong&gt;virtual Ethernet (veth)&lt;/strong&gt; pairs: one end (&lt;code&gt;vethXXXX&lt;/code&gt;) on the host, the other (&lt;code&gt;eth0&lt;/code&gt;) in the container.&lt;/p&gt;

&lt;p&gt;Path: nginx → &lt;code&gt;docker0&lt;/code&gt; → &lt;code&gt;vethXXXX&lt;/code&gt; → container’s &lt;code&gt;eth0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check the bridge:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Show Docker bridge (needs bridge-utils)&lt;/span&gt;
brctl show docker0
&lt;span class="c"&gt;# Example: docker0 ... interfaces: veth1234&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Docker networking: &lt;a href="https://docs.docker.com/network/bridge/" rel="noopener noreferrer"&gt;Docker bridge docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Container App and Return Trip
&lt;/h2&gt;

&lt;p&gt;In the container, the packet hits its &lt;code&gt;eth0&lt;/code&gt; (the one inside the container, this one is virtual) and reaches the Python app on port 8000. The app responds, and the packet reverses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Container &lt;code&gt;eth0&lt;/code&gt; → &lt;code&gt;vethXXXX&lt;/code&gt; → &lt;code&gt;docker0&lt;/code&gt; → nginx → &lt;code&gt;eth0&lt;/code&gt; → browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On return, &lt;code&gt;filter:FORWARD&lt;/code&gt; ensures forwarding is allowed, and &lt;code&gt;nat:POSTROUTING&lt;/code&gt; applies &lt;strong&gt;Source NAT (SNAT)&lt;/strong&gt;, rewriting the source from &lt;code&gt;172.17.0.2&lt;/code&gt; to &lt;code&gt;203.0.113.10&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add SNAT:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Add SNAT for outbound traffic (run as root)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-s&lt;/span&gt; 172.17.0.0/16 &lt;span class="nt"&gt;-o&lt;/span&gt; eth0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE
&lt;span class="c"&gt;# Verify: iptables -t nat -L POSTROUTING -v -n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Simple Python app:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app.py - Run: python app.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;http.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPServer&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from container!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HTTPServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serve_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# Run; test with: curl localhost:8000
# Output: Hello from container!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Save and run with &lt;code&gt;python app.py&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why This MaThe &lt;strong&gt;Linux networking stack&lt;/strong&gt; is the kernel’s machinery: interfaces receive packets, iptables’ tables (&lt;code&gt;filter&lt;/code&gt; for security, &lt;code&gt;nat&lt;/code&gt; for routing) and chains (&lt;code&gt;INPUT&lt;/code&gt;, &lt;code&gt;FORWARD&lt;/code&gt;) process them, and routing delivers them. It’s what powers every &lt;code&gt;curl&lt;/code&gt; or server.
&lt;/h2&gt;

&lt;p&gt;Understanding this helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debug with &lt;code&gt;ip addr&lt;/code&gt;, &lt;code&gt;iptables -L&lt;/code&gt;, or &lt;code&gt;tcpdump&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Secure systems by crafting precise iptables rules.&lt;/li&gt;
&lt;li&gt;Design networks, like Docker setups, with confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next time you see &lt;code&gt;veth1234&lt;/code&gt; or a cryptic iptables rule, you’ll know its place in the packet’s journey—and how to control it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>webdev</category>
      <category>programming</category>
      <category>linux</category>
      <category>networking</category>
    </item>
    <item>
      <title>A Deep Dive Into How Go Modules Work</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Sun, 28 Sep 2025 19:25:02 +0000</pubDate>
      <link>https://dev.to/shrsv/a-deep-dive-into-how-go-modules-work-46p3</link>
      <guid>https://dev.to/shrsv/a-deep-dive-into-how-go-modules-work-46p3</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Go modules are the standard way to manage dependencies in Go projects since Go 1.11. They help organize code, handle versions, and make builds reproducible. This article breaks down how modules function, with practical examples to get you up to speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Basics of Go Modules
&lt;/h2&gt;

&lt;p&gt;Go modules provide a system for versioning and dependency management. Before modules, Go used GOPATH, which often led to version conflicts. Modules solve this by defining a module as a collection of packages with a unique path and version.&lt;/p&gt;

&lt;p&gt;A module is identified by its &lt;strong&gt;module path&lt;/strong&gt;, like &lt;code&gt;github.com/user/project&lt;/code&gt;. Each module has a &lt;code&gt;go.mod&lt;/code&gt; file that lists dependencies and their versions.&lt;/p&gt;

&lt;p&gt;To enable modules, set the &lt;code&gt;GO111MODULE&lt;/code&gt; environment variable to &lt;code&gt;auto&lt;/code&gt; or &lt;code&gt;on&lt;/code&gt;, but in recent Go versions, it's on by default outside GOPATH.&lt;/p&gt;

&lt;p&gt;Here's a simple example to create a module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// main.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, Modules!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run &lt;code&gt;go mod init example.com/mymodule&lt;/code&gt; in the directory with &lt;code&gt;main.go&lt;/code&gt;. This creates a &lt;code&gt;go.mod&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module example.com/mymodule

go 1.21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Build and run with &lt;code&gt;go build&lt;/code&gt; and &lt;code&gt;./mymodule&lt;/code&gt; (or &lt;code&gt;mymodule.exe&lt;/code&gt; on Windows). Output: Hello, Modules!&lt;/p&gt;

&lt;p&gt;For more on module basics, check the official Go documentation: &lt;a href="https://go.dev/doc/modules/gomod-ref" rel="noopener noreferrer"&gt;Modules Overview&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Your First Go Module Step by Step
&lt;/h2&gt;

&lt;p&gt;Start with an empty directory. Create a file &lt;code&gt;greet.go&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// greet.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, %s!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then &lt;code&gt;main.go&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// main.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"example.com/mymodule/greet"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Developer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Initialize the module: &lt;code&gt;go mod init example.com/mymodule&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;go.mod&lt;/code&gt; now exists. To tidy dependencies (though none yet), run &lt;code&gt;go mod tidy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Build: &lt;code&gt;go build&lt;/code&gt;. Run: &lt;code&gt;./mymodule&lt;/code&gt;. Output: Hello, Developer!&lt;/p&gt;

&lt;p&gt;This setup shows how packages within a module import each other using the module path.&lt;/p&gt;
&lt;h2&gt;
  
  
  Inside the go.mod File: Key Elements Explained
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;go.mod&lt;/code&gt; file is the heart of a module. It declares the module path, Go version, dependencies, and more.&lt;/p&gt;

&lt;p&gt;Key directives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;module&lt;/strong&gt;: Defines the module path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;go&lt;/strong&gt;: Specifies the minimum Go version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;require&lt;/strong&gt;: Lists direct dependencies with versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;replace&lt;/strong&gt;: Overrides a dependency's path or version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;exclude&lt;/strong&gt;: Skips specific versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;retract&lt;/strong&gt;: Marks versions as retracted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example &lt;code&gt;go.mod&lt;/code&gt; after adding a dependency:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module example.com/mymodule

go 1.21

require github.com/google/uuid v1.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run &lt;code&gt;go mod edit -require=github.com/google/uuid@v1.3.0&lt;/code&gt; to add it manually, or use &lt;code&gt;go get&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To understand directives better, see &lt;a href="https://go.dev/ref/mod#go-mod-file" rel="noopener noreferrer"&gt;go.mod Reference&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding and Updating Dependencies Effectively
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;go get&lt;/code&gt; to add dependencies. It updates &lt;code&gt;go.mod&lt;/code&gt; and downloads modules.&lt;/p&gt;

&lt;p&gt;Example: Add &lt;code&gt;github.com/google/uuid&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;main.go&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// main.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/google/uuid"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run &lt;code&gt;go get github.com/google/uuid&lt;/code&gt;. This adds to &lt;code&gt;go.mod&lt;/code&gt; and creates &lt;code&gt;go.sum&lt;/code&gt; for checksums.&lt;/p&gt;

&lt;p&gt;To update: &lt;code&gt;go get github.com/google/uuid@latest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go.sum&lt;/code&gt; ensures integrity; it lists hashes for modules.&lt;/p&gt;

&lt;p&gt;For a table of common commands:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;go get pkg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add or update dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;go mod tidy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove unused, add missing deps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;go mod why pkg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Explain why a package is needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;go list -m all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all modules and versions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  How Versioning and Semantic Versioning Fit In
&lt;/h2&gt;

&lt;p&gt;Go uses semantic versioning (SemVer) like v1.2.3. Modules support major versions via suffixes: v2+ in the path, like &lt;code&gt;example.com/mymodule/v2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When requiring, specify versions: &lt;code&gt;require example.com/other v1.0.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Go resolves versions using &lt;strong&gt;minimal version selection (MVS)&lt;/strong&gt;: Picks the highest version that satisfies all requirements.&lt;/p&gt;

&lt;p&gt;Example: If one dep requires v1.2.0 and another v1.3.0, it chooses v1.3.0 if compatible.&lt;/p&gt;

&lt;p&gt;To tag a version: &lt;code&gt;git tag v1.0.0&lt;/code&gt; and push.&lt;/p&gt;

&lt;p&gt;Pseudo-versions like &lt;code&gt;v0.0.0-20230929123456-abcdef123456&lt;/code&gt; are used for untagged commits.&lt;/p&gt;

&lt;p&gt;For details on versioning: &lt;a href="https://go.dev/ref/mod#versions" rel="noopener noreferrer"&gt;Module Versions&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Working with Multiple Modules in Workspaces
&lt;/h2&gt;

&lt;p&gt;Workspaces allow editing multiple modules together, useful for monorepos.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;go.work&lt;/code&gt; with &lt;code&gt;go work init&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add modules: &lt;code&gt;go work use ./mod1 ./mod2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;workspace/

&lt;ul&gt;
&lt;li&gt;mod1/&lt;/li&gt;
&lt;li&gt;go.mod&lt;/li&gt;
&lt;li&gt;main.go&lt;/li&gt;
&lt;li&gt;mod2/&lt;/li&gt;
&lt;li&gt;go.mod&lt;/li&gt;
&lt;li&gt;lib.go&lt;/li&gt;
&lt;li&gt;go.work&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;go.work&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go 1.21

use (
    ./mod1
    ./mod2
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In mod1's main.go, import mod2 using its path.&lt;/p&gt;

&lt;p&gt;This overrides &lt;code&gt;go.mod&lt;/code&gt; replaces for local development.&lt;/p&gt;
&lt;h2&gt;
  
  
  Troubleshooting Common Module Issues
&lt;/h2&gt;

&lt;p&gt;Common problems include proxy issues, checksum mismatches, or invalid paths.&lt;/p&gt;

&lt;p&gt;For checksum errors: Run &lt;code&gt;go mod verify&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If behind a proxy, set &lt;code&gt;GOPROXY=https://proxy.golang.org,direct&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Invalid module path: Ensure it starts with a domain like &lt;code&gt;example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example fix for a bad import:&lt;/p&gt;

&lt;p&gt;If import fails, check &lt;code&gt;go.mod&lt;/code&gt; for correct require.&lt;/p&gt;

&lt;p&gt;Table of errors:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error Type&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Checksum mismatch&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;go mod download&lt;/code&gt; or delete cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Module not found&lt;/td&gt;
&lt;td&gt;Check network or GOPROXY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version conflict&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;go mod graph&lt;/code&gt; to inspect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For proxy setup: &lt;a href="https://go.dev/ref/mod#environment-variables" rel="noopener noreferrer"&gt;GOPROXY Environment&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Advanced Techniques for Module Management
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;replace&lt;/code&gt; in &lt;code&gt;go.mod&lt;/code&gt; for local forks: &lt;code&gt;replace github.com/other/mod =&amp;gt; ../local/mod&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vendoring: &lt;code&gt;go mod vendor&lt;/code&gt; copies deps to &lt;code&gt;vendor/&lt;/code&gt; for offline builds.&lt;/p&gt;

&lt;p&gt;Minimal modules: Keep &lt;code&gt;go.mod&lt;/code&gt; clean with &lt;code&gt;go mod tidy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For private modules, set &lt;code&gt;GOPRIVATE=example.com/private&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example with replace:&lt;/p&gt;

&lt;p&gt;Add to &lt;code&gt;go.mod&lt;/code&gt;: &lt;code&gt;replace github.com/google/uuid =&amp;gt; ./local/uuid&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This points to a local directory.&lt;/p&gt;

&lt;p&gt;Go modules evolve with each release, so check release notes for updates. Mastering them ensures reliable, scalable projects. Experiment with these examples in your setup to solidify your understanding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>programming</category>
      <category>go</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Try These Under The Radar Golang Features to Do More With Less</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Fri, 26 Sep 2025 19:21:38 +0000</pubDate>
      <link>https://dev.to/shrsv/try-these-under-the-radar-golang-features-to-do-more-with-less-1o86</link>
      <guid>https://dev.to/shrsv/try-these-under-the-radar-golang-features-to-do-more-with-less-1o86</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Go's simplicity is one of its biggest strengths, but it packs some under-the-radar features that can shave hours off your development time. In this post, we'll explore capabilities like build constraints, object pooling, and advanced error handling. These aren't always front-and-center in tutorials, but they solve real-world problems efficiently. Whether you're optimizing performance or streamlining workflows, these tools can make your code cleaner and faster. Let's get into the details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customize Builds with Constraints for Platform-Specific Code
&lt;/h2&gt;

&lt;p&gt;Build constraints let you include or exclude code based on conditions like OS, architecture, or custom tags. This keeps your codebase clean without runtime checks, which is great for cross-platform apps.&lt;/p&gt;

&lt;p&gt;For example, you might have platform-specific implementations. Add a comment like &lt;code&gt;//go:build darwin&lt;/code&gt; at the top of a file to make it compile only on macOS.&lt;/p&gt;

&lt;p&gt;Here's a complete example. Create two files: &lt;code&gt;hello_darwin.go&lt;/code&gt; and &lt;code&gt;hello_linux.go&lt;/code&gt;, plus a main file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hello_darwin.go&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build darwin&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from macOS!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No, that's not right. Build constraints apply to files, and main should be separate.&lt;/p&gt;

&lt;p&gt;Better: &lt;/p&gt;

&lt;p&gt;main.go:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;darwin.go:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build darwin&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from macOS!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No, package main in both? Actually, for same package.&lt;/p&gt;

&lt;p&gt;Correct way: files in same package.&lt;/p&gt;

&lt;p&gt;Let's do:&lt;/p&gt;

&lt;p&gt;main.go:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;message_darwin.go:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build darwin&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello from macOS!"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;message_linux.go:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build linux&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello from Linux!"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To compile: &lt;code&gt;go build&lt;/code&gt; on respective OS.&lt;/p&gt;

&lt;p&gt;Output on macOS: // Hello from macOS!&lt;/p&gt;

&lt;p&gt;On Linux: // Hello from Linux!&lt;/p&gt;

&lt;p&gt;You can also use custom tags like &lt;code&gt;//go:build prod&lt;/code&gt; and compile with &lt;code&gt;go build -tags prod&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This avoids if-else bloat in code. For more on syntax, check the &lt;a href="https://pkg.go.dev/cmd/go#hdr-Build_constraints" rel="noopener noreferrer"&gt;official build constraints doc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduces binary size&lt;/strong&gt; by excluding unused code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improves readability&lt;/strong&gt; without conditional logic.&lt;/li&gt;
&lt;li&gt;Works with modules seamlessly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Reuse Objects Efficiently Using sync.Pool
&lt;/h2&gt;

&lt;p&gt;sync.Pool provides a way to reuse temporary objects, reducing garbage collection pressure in high-throughput apps like servers.&lt;/p&gt;

&lt;p&gt;It's ideal for allocating buffers or structs that are created and discarded frequently. The pool manages a cache of objects, and you can put/get them as needed.&lt;/p&gt;

&lt;p&gt;Example: In a web server, reuse byte slices for responses.&lt;/p&gt;

&lt;p&gt;Complete code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Get from pool&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="c"&gt;// Output: Hello, World!&lt;/span&gt;

    &lt;span class="c"&gt;// Put back&lt;/span&gt;
    &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Get again, should reuse&lt;/span&gt;
    &lt;span class="n"&gt;buf2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// Output: 1024 (reused)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This runs without errors. The New func creates objects on miss.&lt;/p&gt;

&lt;p&gt;Pools are goroutine-safe but cleared during GC, so use for short-lived objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cuts allocation overhead&lt;/strong&gt; in loops or handlers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread-safe&lt;/strong&gt; by design.&lt;/li&gt;
&lt;li&gt;Avoid storing stateful objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For benchmarks showing gains, see Go's &lt;a href="https://pkg.go.dev/sync#Pool" rel="noopener noreferrer"&gt;sync package docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Handle Timeouts and Cancellations with Context
&lt;/h2&gt;

&lt;p&gt;The context package lets you propagate cancellation signals, deadlines, and values across API boundaries, preventing resource leaks in concurrent code.&lt;/p&gt;

&lt;p&gt;Use it for HTTP requests, database queries, or goroutines that might outlive their usefulness.&lt;/p&gt;

&lt;p&gt;Example: A function that simulates work with timeout.&lt;/p&gt;

&lt;p&gt;Complete code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;doWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Work completed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;doWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Output: context deadline exceeded&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, the timeout triggers cancellation.&lt;/p&gt;

&lt;p&gt;You can nest contexts or pass values like user IDs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prevents goroutine leaks&lt;/strong&gt; by signaling done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composable&lt;/strong&gt; with WithValue, WithDeadline.&lt;/li&gt;
&lt;li&gt;Standard in libraries like net/http.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Improve Error Handling with errors.Is and errors.As
&lt;/h2&gt;

&lt;p&gt;The errors package offers Is and As for checking wrapped errors, making it easier to handle specific error types without string matching.&lt;/p&gt;

&lt;p&gt;This is useful in layered apps where errors get wrapped with context.&lt;/p&gt;

&lt;p&gt;Example: Wrap an error and check it later.&lt;/p&gt;

&lt;p&gt;Complete code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"errors"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ErrNotFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;findItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to find: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;findItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Item not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Output: Item not found&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PathError&lt;/span&gt; &lt;span class="c"&gt;// Assuming import "os"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Would work if wrapped error is PathError&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Wait, in this example, it's not PathError, but shows As usage.&lt;/p&gt;

&lt;p&gt;Import "os" for PathError.&lt;/p&gt;

&lt;p&gt;But to keep simple, the Is works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chainable&lt;/strong&gt; with %w in fmt.Errorf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-safe&lt;/strong&gt; checks with As.&lt;/li&gt;
&lt;li&gt;Reduces brittle string comparisons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See &lt;a href="https://pkg.go.dev/errors" rel="noopener noreferrer"&gt;errors package docs&lt;/a&gt; for unwrap details.&lt;/p&gt;
&lt;h2&gt;
  
  
  Speed Up Tests with Parallel Execution
&lt;/h2&gt;

&lt;p&gt;In testing, t.Parallel() lets tests run concurrently, cutting down suite time on multi-core machines.&lt;/p&gt;

&lt;p&gt;Mark independent tests to run in parallel, while setup can stay serial.&lt;/p&gt;

&lt;p&gt;Example: Two tests that can run together.&lt;/p&gt;

&lt;p&gt;Complete code (save as example_test.go):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestSlowOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Assert something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestSlowTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parallel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Assert something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Run tests&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run with &lt;code&gt;go test -v&lt;/code&gt;. Without parallel, ~2s; with, ~1s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Boosts CI/CD speed&lt;/strong&gt; for large suites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe for independent tests&lt;/strong&gt;; avoid shared state.&lt;/li&gt;
&lt;li&gt;Use with -parallel flag for control.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Embed Files Directly into Binaries
&lt;/h2&gt;

&lt;p&gt;The embed package (Go 1.16+) lets you include files like templates or assets in your binary, simplifying deployment.&lt;/p&gt;

&lt;p&gt;No need for separate assets folders in production.&lt;/p&gt;

&lt;p&gt;Example: Embed a text file and read it.&lt;/p&gt;

&lt;p&gt;Complete code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"embed"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;//go:embed hello.txt&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="n"&gt;embed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FS&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// Output: assuming hello.txt contains "Hello, Embedded!"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Create hello.txt with "Hello, Embedded!".&lt;/p&gt;

&lt;p&gt;Build and run; file is inside binary.&lt;/p&gt;

&lt;p&gt;You can embed directories too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-file deploys&lt;/strong&gt; for CLIs or servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-only access&lt;/strong&gt; via embed.FS.&lt;/li&gt;
&lt;li&gt;Works with http.FileServer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check &lt;a href="https://pkg.go.dev/embed" rel="noopener noreferrer"&gt;embed package docs&lt;/a&gt; for patterns.&lt;/p&gt;
&lt;h2&gt;
  
  
  Achieve Lock-Free Updates with Atomic Operations
&lt;/h2&gt;

&lt;p&gt;The sync/atomic package provides functions for atomic reads/writes, avoiding mutexes for simple concurrent updates.&lt;/p&gt;

&lt;p&gt;Useful for counters or flags in high-concurrency scenarios.&lt;/p&gt;

&lt;p&gt;Example: Atomic counter in goroutines.&lt;/p&gt;

&lt;p&gt;Complete code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"sync/atomic"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;atomic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddInt64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Output: 1000&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Without atomic, race conditions possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster than mutexes&lt;/strong&gt; for primitives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations like Load, Store, CompareAndSwap&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Detect races with -race flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Tailor JSON Handling with Custom Marshaling
&lt;/h2&gt;

&lt;p&gt;Implement json.Marshaler/Unmarshaler for custom JSON logic, like formatting dates or validating fields.&lt;/p&gt;

&lt;p&gt;This keeps structs clean while handling edge cases.&lt;/p&gt;

&lt;p&gt;Example: Custom time format.&lt;/p&gt;

&lt;p&gt;Complete code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;CustomTime&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="n"&gt;CustomTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;MarshalJSON&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;When&lt;/span&gt; &lt;span class="n"&gt;CustomTime&lt;/span&gt; &lt;span class="s"&gt;`json:"when"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;When&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CustomTime&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()}}&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// Output: {"when":"2025-09-27"} (approx, based on date)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This overrides default time format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexible serialization&lt;/strong&gt; without extracode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pairs with struct tags&lt;/strong&gt; for field names.&lt;/li&gt;
&lt;li&gt;Use for enums or computed fields.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Incorporating these features into your daily Go work can lead to more efficient codebases and quicker iterations. Start with one or two in your next project—build constraints for multi-platform tweaks or sync.Pool for performance hotspots—and measure the impact. Over time, they'll become go-to tools in your toolkit, helping you focus on logic rather than boilerplate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>go</category>
      <category>programming</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Gatsby or Astro: Picking the Right Tool for Content-Heavy Websites</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Wed, 24 Sep 2025 17:57:31 +0000</pubDate>
      <link>https://dev.to/shrsv/gatsby-or-astro-picking-the-right-tool-for-content-heavy-websites-54gm</link>
      <guid>https://dev.to/shrsv/gatsby-or-astro-picking-the-right-tool-for-content-heavy-websites-54gm</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When building websites focused on content like blogs,documentation sites, or portfolios, Gatsby and Astro stand out as popular choices. Both frameworks help developers create fast, modern sites, but they differ in architecture, performance, and flexibility. This post breaks down their key aspects to help you decide which fits your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inside Gatsby: Static Sites with React Power
&lt;/h2&gt;

&lt;p&gt;Gatsby is a static site generator built on React. It pulls in data from various sources during build time and generates HTML files. This means your site loads quickly since everything is pre-rendered.&lt;/p&gt;

&lt;p&gt;Key features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL for data querying&lt;/strong&gt;: Gatsby uses GraphQL to fetch content from Markdown, APIs, or CMS like Contentful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugin ecosystem&lt;/strong&gt;: Thousands of plugins for SEO, image optimization, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React components&lt;/strong&gt;: Build dynamic UIs while keeping the site static.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a simple blog setup in Gatsby, start by installing it globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; gatsby-cli
gatsby new my-gatsby-blog https://github.com/gatsbyjs/gatsby-starter-blog
&lt;span class="nb"&gt;cd &lt;/span&gt;my-gatsby-blog
gatsby develop
&lt;span class="c"&gt;# Output: Server starts at http://localhost:8000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In &lt;code&gt;src/pages/index.js&lt;/code&gt;, you can query posts:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Blog Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allMarkdownRemark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;excerpt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    allMarkdownRemark {
      nodes {
        id
        frontmatter {
          title
        }
        excerpt
      }
    }
  }
`&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Renders&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;Markdown&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Gatsby handles routing automatically and optimizes images via plugins like &lt;code&gt;gatsby-image&lt;/code&gt;. Check the official docs for more on data sourcing: &lt;a href="https://www.gatsbyjs.com/docs/tutorial/part-4/" rel="noopener noreferrer"&gt;Gatsby Data Layer&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Astro's Core: Islands of Interactivity
&lt;/h2&gt;

&lt;p&gt;Astro focuses on shipping less JavaScript by default. It renders pages to HTML at build time but allows "islands" of interactive components from frameworks like React or Vue.&lt;/p&gt;

&lt;p&gt;Standout points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Framework-agnostic&lt;/strong&gt;: Mix components from different libraries without lock-in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partial hydration&lt;/strong&gt;: Only hydrate interactive parts, keeping the rest static.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content collections&lt;/strong&gt;: Built-in support for Markdown and MDX with schema validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To set up a basic Astro site:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create astro@latest my-astro-blog &lt;span class="nt"&gt;--template&lt;/span&gt; blog
&lt;span class="nb"&gt;cd &lt;/span&gt;my-astro-blog
npm run dev
&lt;span class="c"&gt;# Output: Server runs at http://localhost:4321&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For displaying content, use collections in &lt;code&gt;src/content/config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defineCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogCollection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineCollection&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blogCollection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Defines&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;blog&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, in &lt;code&gt;src/pages/index.astro&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
import { getCollection } from 'astro:content';

const posts = await getCollection('blog');
---
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Blog&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Posts&amp;lt;/h1&amp;gt;
    &amp;lt;ul&amp;gt;
      {posts.map(post =&amp;gt; (
        &amp;lt;li&amp;gt;
          &amp;lt;a href={`/blog/${post.slug}`}&amp;gt;{post.data.title}&amp;lt;/a&amp;gt;
        &amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
# Output: Generates a static index page listing blog posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Astro's syntax mixes HTML with JavaScript expressions. For deeper dives, see &lt;a href="https://docs.astro.build/en/guides/content-collections/" rel="noopener noreferrer"&gt;Astro Content Collections&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Speed and Performance: Where They Differ
&lt;/h2&gt;

&lt;p&gt;Performance is crucial for content sites with images and text. Gatsby pre-builds everything, leading to fast initial loads but longer build times for large sites. Astro often builds faster since it avoids bundling unused JS.&lt;/p&gt;

&lt;p&gt;In benchmarks, Astro sites can load 20-50% faster due to minimal client-side code. Gatsby shines with its image processing, reducing file sizes automatically.&lt;/p&gt;

&lt;p&gt;Here's a quick comparison table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Gatsby&lt;/th&gt;
&lt;th&gt;Astro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Build Time&lt;/td&gt;
&lt;td&gt;Supports Incremental Builds&lt;/td&gt;
&lt;td&gt;No real incremental builds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Render Time&lt;/td&gt;
&lt;td&gt;Slower for big sites (full React bundle)&lt;/td&gt;
&lt;td&gt;Faster, selective rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page Load Speed&lt;/td&gt;
&lt;td&gt;Excellent with pre-rendering&lt;/td&gt;
&lt;td&gt;Superior with zero-JS default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bundle Size&lt;/td&gt;
&lt;td&gt;Larger if interactive&lt;/td&gt;
&lt;td&gt;Smaller, islands only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test your own site with tools like Lighthouse. For Gatsby optimizations, refer to &lt;a href="https://www.gatsbyjs.com/docs/how-to/performance/" rel="noopener noreferrer"&gt;Gatsby Performance Guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Managing Content Sources Effectively
&lt;/h2&gt;

&lt;p&gt;Both handle content from Markdown, but Gatsby integrates deeply with CMS via plugins. Astro uses file-based routing and collections for simplicity.&lt;/p&gt;

&lt;p&gt;In Gatsby, connect to a headless CMS like Sanity:&lt;/p&gt;

&lt;p&gt;Install plugin: &lt;code&gt;npm install gatsby-source-sanity&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add to &lt;code&gt;gatsby-config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-source-sanity`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-project-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Output: Pulls Sanity data into GraphQL layer for querying&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Query in pages as before.&lt;/p&gt;

&lt;p&gt;Astro fetches external data at build time or via endpoints. For Markdown, it's native—no plugins needed.&lt;/p&gt;

&lt;p&gt;Bold tip: &lt;strong&gt;If your site grows to hundreds of pages, Astro's content collections prevent schema errors early.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup and Daily Workflow Comparison
&lt;/h2&gt;

&lt;p&gt;Gatsby requires Node.js and familiarity with React. Setup involves configuring plugins in &lt;code&gt;gatsby-config.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Astro's CLI is straightforward, with less boilerplate. You edit &lt;code&gt;.astro&lt;/code&gt; files directly, which feels like enhanced HTML.&lt;/p&gt;

&lt;p&gt;Developer pain points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gatsby: Debugging GraphQL can be tricky for beginners.&lt;/li&gt;
&lt;li&gt;Astro: Learning islands if you need interactivity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both support hot module replacement for fast dev servers. Astro often feels lighter for quick iterations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Built-in SEO and Accessibility Tools
&lt;/h2&gt;

&lt;p&gt;SEO is baked into both. Gatsby generates sitemaps and meta tags via plugins like &lt;code&gt;gatsby-plugin-sitemap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Astro handles SEO with frontmatter in pages:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
title: 'My Post'
description: 'A description here'
---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Key difference&lt;/strong&gt;: Gatsby's React base makes dynamic meta tags easier for personalized content.&lt;/p&gt;

&lt;p&gt;For accessibility, both encourage semantic HTML, but Astro's static focus reduces JS-related issues.&lt;/p&gt;

&lt;p&gt;Explore Astro's SEO features: &lt;a href="https://docs.astro.build/en/guides/seo/" rel="noopener noreferrer"&gt;Astro SEO Guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ecosystem Strength: Plugins and Community
&lt;/h2&gt;

&lt;p&gt;Gatsby boasts over 2,500 plugins, covering themes to e-commerce. Its community is mature, with many starters.&lt;/p&gt;

&lt;p&gt;Astro's ecosystem is growing fast, with integrations for major frameworks. It has fewer plugins but emphasizes composability.&lt;/p&gt;

&lt;p&gt;If you're in the React world, Gatsby feels like home. Astro appeals for multi-framework projects.&lt;/p&gt;

&lt;p&gt;Community forums: Gatsby has active Slack; Astro uses Discord.&lt;/p&gt;
&lt;h2&gt;
  
  
  Making the Choice Based on Your Needs
&lt;/h2&gt;

&lt;p&gt;Consider your project's scale. For highly interactive content sites with heavy data integration, Gatsby provides robust tools through its GraphQL layer and plugins—ideal if you're already using React.&lt;/p&gt;

&lt;p&gt;Opt for Astro if you prioritize speed and minimal JS, especially for mostly static conTent with spots of interactivity. It's great for migrating from older static generators or starting fresh with flexibility.&lt;/p&gt;

&lt;p&gt;Test both with a prototype: Spin up a small blog in each and measure build times, load speeds, and ease of adding features. Your team's skills matter too—React devs lean Gatsby, while HTML/JS purists prefer Astro.&lt;/p&gt;

&lt;p&gt;Ultimately, both deliver excellent content-driven sites, so align with your performance goals and workflow preferences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Unpacking Git's Branching: A Look at the Internals</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Tue, 23 Sep 2025 19:43:26 +0000</pubDate>
      <link>https://dev.to/shrsv/unpacking-gits-branching-a-look-at-the-internals-b4a</link>
      <guid>https://dev.to/shrsv/unpacking-gits-branching-a-look-at-the-internals-b4a</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;Git branching lets developers work on features or fixes without disrupting the main codebase. At its core, branches are lightweight pointers to commits, making them efficient for managing parallel development. This article breaks down how branching operates inside Git, with examples to show the mechanics in action.
&lt;h2&gt;
  
  
  Branches as Simple Pointers
&lt;/h2&gt;

&lt;p&gt;In Git, a branch isn't a full copy of the code—it's a reference to a specific commit. Stored in the &lt;code&gt;.git/refs/heads/&lt;/code&gt; directory, each branch file contains the SHA-1 hash of the commit it points to. This design keeps branching fast and cheap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Branches move forward with new commits, updating their reference automatically.&lt;/p&gt;

&lt;p&gt;For example, start with a fresh repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize a new Git repository&lt;/span&gt;
git init my-repo
&lt;span class="nb"&gt;cd &lt;/span&gt;my-repo

&lt;span class="c"&gt;# Create and commit a file&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Initial content"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; file.txt
git add file.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit"&lt;/span&gt;
&lt;span class="c"&gt;# Output: [master (root-commit) abc123] Initial commit&lt;/span&gt;

&lt;span class="c"&gt;# Check the branch reference&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; .git/refs/heads/master
&lt;span class="c"&gt;# Output: abc1234567890abcdef1234567890abcdef1234 (example SHA)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, &lt;code&gt;master&lt;/code&gt; points to the commit hash. Adding another commit shifts this pointer.&lt;/p&gt;

&lt;p&gt;Git documentation on branches: &lt;a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell" rel="noopener noreferrer"&gt;git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  HEAD: Git's Current Position Marker
&lt;/h2&gt;

&lt;p&gt;HEAD is a special reference that tracks where you are in the repository. It usually points to a branch, like &lt;code&gt;refs/heads/main&lt;/code&gt;, but can detach to point directly at a commit. This controls what &lt;code&gt;git status&lt;/code&gt; and commits affect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; When HEAD points to a branch, commits update that branch's pointer.&lt;/p&gt;

&lt;p&gt;View HEAD in action:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# After initial setup from previous example&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature
&lt;span class="c"&gt;# Output: Switched to a new branch 'feature'&lt;/span&gt;

&lt;span class="c"&gt;# Inspect HEAD&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; .git/HEAD
&lt;span class="c"&gt;# Output: ref: refs/heads/feature&lt;/span&gt;

&lt;span class="c"&gt;# Commit something new&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Feature addition"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; file.txt
git add file.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add feature"&lt;/span&gt;
&lt;span class="c"&gt;# Output: [feature def456] Add feature&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;HEAD now references the &lt;code&gt;feature&lt;/code&gt; branch, which points to the new commit.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Branches: Instant and Low-Cost
&lt;/h2&gt;

&lt;p&gt;Git creates a branch by writing a new file in &lt;code&gt;.git/refs/heads/&lt;/code&gt; with the current commit's hash. No files are copied—it's just a 41-byte file (40 for the hash plus a newline).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Branches start from the current HEAD, inheriting the commit history.&lt;/p&gt;

&lt;p&gt;Try creating one:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Continuing from previous&lt;/span&gt;
git branch bugfix
&lt;span class="c"&gt;# No output, but creates the branch&lt;/span&gt;

&lt;span class="c"&gt;# List branches&lt;/span&gt;
git branch
&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;#   bugfix&lt;/span&gt;
&lt;span class="c"&gt;# * feature&lt;/span&gt;
&lt;span class="c"&gt;#   master&lt;/span&gt;

&lt;span class="c"&gt;# Check the new branch reference&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; .git/refs/heads/bugfix
&lt;span class="c"&gt;# Output: def4567890abcdef1234567890abcdef1234567 (matches feature's current commit)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This shows &lt;code&gt;bugfix&lt;/code&gt; points to the same commit as &lt;code&gt;feature&lt;/code&gt; at creation time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Switching Branches with Checkout
&lt;/h2&gt;

&lt;p&gt;Checkout updates the working directory to match the target branch's commit. Git swaps files in the index and worktree, using the tree-ish (commit) the branch references.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; If conflicts arise, Git aborts; otherwise, HEAD updates to the new branch.&lt;/p&gt;

&lt;p&gt;Example of switching:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From feature branch&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bug fix content"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bug.txt
git add bug.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Fix bug on bugfix"&lt;/span&gt;  &lt;span class="c"&gt;# But wait, we're on feature—switch first&lt;/span&gt;

git checkout bugfix
&lt;span class="c"&gt;# Output: Switched to branch 'bugfix'&lt;/span&gt;

&lt;span class="c"&gt;# Now commit on bugfix&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bug fix content"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bug.txt
git add bug.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Fix bug"&lt;/span&gt;
&lt;span class="c"&gt;# Output: [bugfix ghi789] Fix bug&lt;/span&gt;

&lt;span class="c"&gt;# Switch back&lt;/span&gt;
git checkout feature
&lt;span class="c"&gt;# Output: Switched to branch 'feature'&lt;/span&gt;
&lt;span class="c"&gt;# Note: bug.txt is gone from worktree&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The worktree reflects the branch's state after checkout.&lt;/p&gt;
&lt;h2&gt;
  
  
  Merging: Combining Branch Histories
&lt;/h2&gt;

&lt;p&gt;Merging integrates changes from one branch into another. Git finds the common ancestor and applies differences. Fast-forward merges just move the pointer if no divergence; otherwise, it creates a merge commit.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Merge Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;When It Happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fast-Forward&lt;/td&gt;
&lt;td&gt;Moves target branch to source commit&lt;/td&gt;
&lt;td&gt;No new commits on target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Three-Way Merge&lt;/td&gt;
&lt;td&gt;Creates new commit with two parents&lt;/td&gt;
&lt;td&gt;Divergent histories&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Use &lt;code&gt;--no-ff&lt;/code&gt; to force a merge commit even for fast-forwards.&lt;/p&gt;

&lt;p&gt;Merge example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From previous setup, on master (assuming initial commit)&lt;/span&gt;
git checkout master
&lt;span class="c"&gt;# Output: Switched to branch 'master'&lt;/span&gt;

git merge feature
&lt;span class="c"&gt;# Output: Fast-forward (if no divergence)&lt;/span&gt;
&lt;span class="c"&gt;# Or: Merge made by the 'recursive' strategy. (if three-way)&lt;/span&gt;

&lt;span class="c"&gt;# For three-way, assume divergence&lt;/span&gt;
&lt;span class="c"&gt;# First, commit on master&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Master update"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; file.txt
git add file.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Update on master"&lt;/span&gt;
&lt;span class="c"&gt;# Output: [master jkl012] Update on master&lt;/span&gt;

&lt;span class="c"&gt;# Now merge&lt;/span&gt;
git merge bugfix
&lt;span class="c"&gt;# Output: Auto-merging file.txt (if conflicts, resolve manually)&lt;/span&gt;
&lt;span class="c"&gt;# Merge commit created if successful&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After merge, the target branch includes the source's changes.&lt;/p&gt;

&lt;p&gt;Git merge internals: &lt;a href="https://git-scm.com/docs/git-merge" rel="noopener noreferrer"&gt;git-scm.com/docs/git-merge&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rebasing: Linearizing Branch Commits
&lt;/h2&gt;

&lt;p&gt;Rebasing replays commits from one branch onto another, rewriting history for a cleaner timeline. It moves the branch base, potentially causing conflicts per commit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Avoid rebasing shared branches to prevent history mismatches for collaborators.&lt;/p&gt;

&lt;p&gt;Rebase demo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Setup: Assume feature diverged from master&lt;/span&gt;
git checkout feature
&lt;span class="c"&gt;# Output: Switched to branch 'feature'&lt;/span&gt;

git rebase master
&lt;span class="c"&gt;# Output: Successfully rebased and updated refs/heads/feature.&lt;/span&gt;
&lt;span class="c"&gt;# Or: Conflicts if changes overlap—resolve and git rebase --continue&lt;/span&gt;

&lt;span class="c"&gt;# Before rebase, log might show:&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;--graph&lt;/span&gt;
&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;# * def456 (feature) Add feature&lt;/span&gt;
&lt;span class="c"&gt;# * abc123 (master) Initial commit&lt;/span&gt;

&lt;span class="c"&gt;# After, feature commits sit atop master's latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This keeps history linear but changes commit hashes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Detached HEAD: Working Without a Branch
&lt;/h2&gt;

&lt;p&gt;In detached HEAD, HEAD points directly to a commit, not a branch. Commits here aren't referenced by any branch unless you create one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Use this for temporary experiments; lost commits can be recovered via reflog if needed.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Detach to a commit&lt;/span&gt;
git checkout abc123  &lt;span class="c"&gt;# Initial commit hash&lt;/span&gt;
&lt;span class="c"&gt;# Output: Note: switching to 'abc123'.&lt;/span&gt;
&lt;span class="c"&gt;# You are in 'detached HEAD' state.&lt;/span&gt;

&lt;span class="c"&gt;# Commit in detached state&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Experimental change"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; file.txt
git add file.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Experiment"&lt;/span&gt;
&lt;span class="c"&gt;# Output: [detached HEAD mno345] Experiment&lt;/span&gt;

&lt;span class="c"&gt;# To save, create branch&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; experiment
&lt;span class="c"&gt;# Output: Switched to a new branch 'experiment'&lt;/span&gt;

&lt;span class="c"&gt;# Check log&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;# mno345 (HEAD -&amp;gt; experiment) Experiment&lt;/span&gt;
&lt;span class="c"&gt;# abc123 Initial commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Without branching, the commit risks garbage collection.&lt;/p&gt;
&lt;h2&gt;
  
  
  Remote Branches: Tracking Upstream Changes
&lt;/h2&gt;

&lt;p&gt;Remote branches are read-only references to branches in remote repositories, prefixed like &lt;code&gt;origin/main&lt;/code&gt;. They update on fetch; local branches track them for push/pull.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Set upstream with &lt;code&gt;git branch --set-upstream-to&lt;/code&gt; for easier operations.&lt;/p&gt;

&lt;p&gt;Remote example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add a remote (assume a cloned repo for simplicity)&lt;/span&gt;
&lt;span class="c"&gt;# In a new repo:&lt;/span&gt;
git remote add origin https://github.com/user/repo.git

&lt;span class="c"&gt;# Fetch remotes&lt;/span&gt;
git fetch origin
&lt;span class="c"&gt;# Output: Fetching updates remote refs&lt;/span&gt;

&lt;span class="c"&gt;# List remote branches&lt;/span&gt;
git branch &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;#   origin/master&lt;/span&gt;
&lt;span class="c"&gt;#   origin/feature&lt;/span&gt;

&lt;span class="c"&gt;# Track a remote branch locally&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; local-feature origin/feature
&lt;span class="c"&gt;# Output: Branch 'local-feature' set up to track remote branch 'feature' from 'origin'.&lt;/span&gt;
&lt;span class="c"&gt;# Switched to a new branch 'local-feature'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This syncs local work with remote states.&lt;/p&gt;

&lt;p&gt;Understanding these internals helps debug issues like merge conflicts or lost commits. Experiment in a test repo to see how pointers shift—tools like &lt;code&gt;git log --graph&lt;/code&gt; visualize the structure. For deeper dives, explore Git's object database where commits and trees store the actual data. &lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


 [![git-lrc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzvpkxm9mga1pweneahx.png)](https://github.com/HexmosTech/git-lrc) 
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. 

 git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* 


 Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. 

 ⭐ Star it on GitHub: 
 &lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;


&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;


  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;

&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;

&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Building a Row Echelon Form Checker in Python and Go with Tests</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Mon, 22 Sep 2025 17:36:11 +0000</pubDate>
      <link>https://dev.to/shrsv/building-a-row-echelon-form-checker-in-python-and-go-with-tests-m20</link>
      <guid>https://dev.to/shrsv/building-a-row-echelon-form-checker-in-python-and-go-with-tests-m20</guid>
      <description>&lt;p&gt;Row echelon form is a key concept in linear algebra for simplifying matrices during operations like Gaussian elimination. This post walks through creating a checker function to verify if a matrix is in row echelon form, following specific rules. We'll implement it in Python and Go, add test cases, and explore details with examples. The checker focuses on two main rules: all-zero rows must be at the bottom, and pivot positions must shift rightward in successive rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Row Echelon Form Basics
&lt;/h2&gt;

&lt;p&gt;Row echelon form (REF) structures a matrix so each row starts with zeros followed by a non-zero pivot (if present), and pivots are staggered. This form helps in solving systems of equations by making back-substitution straightforward.&lt;/p&gt;

&lt;p&gt;A matrix in REF looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ 1, 2, 3 ]
[ 0, 1, 4 ]
[ 0, 0, 1 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, pivots are in columns 1, 2, and 3. Not all REF matrices have pivots starting at 1; they can be any non-zero value, but often normalized to 1 in reduced REF (which we're not enforcing here).&lt;/p&gt;

&lt;p&gt;For more on the formal definition, check the &lt;a href="https://en.wikipedia.org/wiki/Row_echelon_form" rel="noopener noreferrer"&gt;Wikipedia page on Row Echelon Form&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Rules for Our REF Checker
&lt;/h2&gt;

&lt;p&gt;Our checker enforces these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All-zero rows at the bottom&lt;/strong&gt;: Any row with all zeros must appear after all non-zero rows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rightward pivot progression&lt;/strong&gt;: The first non-zero element (pivot) in each row must be to the right of the pivot in the row above it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We ignore whether pivots are 1 or if entries above pivots are zero—that's for reduced REF. Our focus is strict REF.&lt;/p&gt;

&lt;p&gt;Consider this invalid example due to a misplaced all-zero row:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Row&lt;/th&gt;
&lt;th&gt;Elements&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;[0, 0, 0]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;[0, 1, 2]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;[0, 0, 3]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This fails the first rule. A valid version would move all-zero to bottom and then swap rows 1 and 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the Checker in Python
&lt;/h2&gt;

&lt;p&gt;In Python, represent matrices as lists of lists. The function iterates through rows, tracks the last pivot column, and checks for all-zero rows out of place.&lt;/p&gt;

&lt;p&gt;Here's the complete function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;  &lt;span class="c1"&gt;# Empty matrix is trivially in REF
&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c1"&gt;# Ensure all rows have same number of columns
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;last_pivot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;seen_zero_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Find the pivot position in this row
&lt;/span&gt;        &lt;span class="n"&gt;pivot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;pivot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pivot_col&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# All-zero row
&lt;/span&gt;            &lt;span class="n"&gt;seen_zero_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;  &lt;span class="c1"&gt;# All-zero rows are okay if at bottom, checked later implicitly
&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;seen_zero_row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;  &lt;span class="c1"&gt;# Non-zero row after zero row
&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pivot_col&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;last_pivot_col&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;  &lt;span class="c1"&gt;# Pivot not to the right
&lt;/span&gt;
        &lt;span class="n"&gt;last_pivot_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pivot_col&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage:
# matrix = [[1, 2, 3], [0, 1, 4], [0, 0, 1]]
# print(is_row_echelon_form(matrix))  # Output: True
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code handles empty matrices and ensures uniform row lengths. It tracks &lt;code&gt;last_pivot_col&lt;/code&gt; to enforce the pivot rule and &lt;code&gt;seen_zero_row&lt;/code&gt; for zero placement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the Python Implementation
&lt;/h2&gt;

&lt;p&gt;Test cases cover valid REF, invalid pivot positions, misplaced zeros, and edge cases like single-row or empty matrices.&lt;/p&gt;

&lt;p&gt;Use Python's &lt;code&gt;unittest&lt;/code&gt; for structured tests. Here's a complete test script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestRowEchelonForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_valid_ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_invalid_pivot_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;  &lt;span class="c1"&gt;# Second row pivot not rightward
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_misplaced_zero_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_all_zero_rows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_empty_matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_single_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_uneven_rows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;  &lt;span class="c1"&gt;# Uneven lengths
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_row_echelon_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# When run, all tests should pass except the invalid ones, which correctly fail.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tests ensure the function behaves as expected. Run this script to verify—expect 7 tests, with no failures if implemented correctly.&lt;/p&gt;

&lt;p&gt;For Python testing docs, see &lt;a href="https://docs.python.org/3/library/unittest.html" rel="noopener noreferrer"&gt;unittest in Python docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Porting the Checker to Go
&lt;/h2&gt;

&lt;p&gt;Go uses slices of slices for matrices. The logic mirrors Python but with Go's type system and error handling for uneven rows.&lt;/p&gt;

&lt;p&gt;Here's the full function in a main package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;isRowEchelonForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="c"&gt;// Empty matrix is in REF&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="c"&gt;// Check all rows have same columns&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;lastPivotCol&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;seenZeroRow&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Find pivot column&lt;/span&gt;
        &lt;span class="n"&gt;pivotCol&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;pivotCol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pivotCol&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// All-zero row&lt;/span&gt;
            &lt;span class="n"&gt;seenZeroRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;seenZeroRow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt; &lt;span class="c"&gt;// Non-zero after zero&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pivotCol&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;lastPivotCol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt; &lt;span class="c"&gt;// Not rightward&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;lastPivotCol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pivotCol&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRowEchelonForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// Output: true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version uses integers for simplicity; adjust to floats if needed for real matrices. Compile and run with &lt;code&gt;go run main.go&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the Go Implementation
&lt;/h2&gt;

&lt;p&gt;Go's &lt;code&gt;testing&lt;/code&gt; package handles tests. We'll mirror Python's cases.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;main_test.go&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"testing"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestIsRowEchelonForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt;  &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
        &lt;span class="n"&gt;want&lt;/span&gt;    &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="p"&gt;}{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"valid_ref"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"invalid_pivot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"misplaced_zero"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"all_zeros"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"empty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"single_row"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"uneven_rows"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tt&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;isRowEchelonForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;tt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"isRowEchelonForm() = %v, want %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Run with 'go test' - expect all tests to pass.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This table-driven test approach makes adding cases easy. Use &lt;code&gt;go test&lt;/code&gt; to execute—look for "ok" output.&lt;/p&gt;

&lt;p&gt;See Go's testing package in &lt;a href="https://pkg.go.dev/testing" rel="noopener noreferrer"&gt;the official docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing Python and Go Approaches
&lt;/h2&gt;

&lt;p&gt;Python's dynamic typing simplifies matrix handling, but Go requires explicit checks for slice lengths. Both use similar loops, but Go's performance shines for large matrices due to compilation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Matrix Rep&lt;/td&gt;
&lt;td&gt;List of lists&lt;/td&gt;
&lt;td&gt;Slice of slices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type Handling&lt;/td&gt;
&lt;td&gt;Flexible (int/float)&lt;/td&gt;
&lt;td&gt;Fixed (int here; use float64)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error Check&lt;/td&gt;
&lt;td&gt;Runtime length check&lt;/td&gt;
&lt;td&gt;Runtime length check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testing&lt;/td&gt;
&lt;td&gt;unittest class-based&lt;/td&gt;
&lt;td&gt;Table-driven with t.Run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Python feels quicker for prototyping, while Go suits production with stricter types.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Edge Cases in Both Languages
&lt;/h2&gt;

&lt;p&gt;Edge cases include non-square matrices, like &lt;a href="https://dev.tovalid"&gt;[1,0],[0,0],[0,0]&lt;/a&gt; or &lt;a href="https://dev.toinvalid%20pivot"&gt;[0,1],[1,0]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In code, our implementations handle these: non-square works as long as rows uniform. For floats, modify comparisons (e.g., use epsilon for zero).&lt;/p&gt;

&lt;p&gt;Test addition: A matrix with leading zeros in rows but correct pivots, like [[0,1,2],[0,0,3]]—valid, pivot cols 1 and 2.&lt;/p&gt;

&lt;p&gt;Both languages' codes pass this without changes. For large matrices, consider efficiency; our O(rows * cols) is fine for most uses.&lt;/p&gt;

&lt;p&gt;Building this checker reinforces linear algebra basics and cross-language skills. Adapt it for reduced REF by adding checks for pivot=1 and upper zeros. Test thoroughly in your projects to catch matrix issues early.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>python</category>
      <category>go</category>
    </item>
    <item>
      <title>Turning PostgreSQL into a Robust Queue for Go Applications</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Sun, 21 Sep 2025 17:45:18 +0000</pubDate>
      <link>https://dev.to/shrsv/turning-postgresql-into-a-robust-queue-for-go-applications-1hob</link>
      <guid>https://dev.to/shrsv/turning-postgresql-into-a-robust-queue-for-go-applications-1hob</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;_PostgreSQL offers built-in features that make it a solid choice for handling queues in your applications. Instead of relying on external systems like RabbitMQ or Redis, you can use PostgreSQL's transactional guarantees and ACID compliance to manage tasks reliably. This approach simplifies your stack, especially if you're already using PostgreSQL for data storage.

&lt;p&gt;In Go, integrating with PostgreSQL for queuing involves standard database operations with some optimizations for concurrency and efficiency. You'll handle enqueuing, dequeuing, and processing tasks while ensuring reliability. This guide walks through the process with practical examples.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Choose PostgreSQL for Queuing Tasks?
&lt;/h2&gt;

&lt;p&gt;Queues manage asynchronous tasks, like sending emails or processing uploads, without blocking your main application flow. PostgreSQL stands out because it supports row-level locking, notifications, and advisory locks, which help avoid common queue issues like race conditions.&lt;/p&gt;

&lt;p&gt;Key advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transactional safety&lt;/strong&gt;: Tasks commit or rollback atomically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No extra infrastructure&lt;/strong&gt;: Reuse your existing database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durability&lt;/strong&gt;: Data persists even on crashes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to dedicated queues, PostgreSQL might not match ultra-high throughput, but it excels for moderate workloads. For instance, if your app processes hundreds of tasks per minute, this setup works well without added complexity.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;PostgreSQL Queue&lt;/th&gt;
&lt;th&gt;Dedicated Queue (e.g., RabbitMQ)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup Complexity&lt;/td&gt;
&lt;td&gt;Low (use existing DB)&lt;/td&gt;
&lt;td&gt;Higher (separate service)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Durability&lt;/td&gt;
&lt;td&gt;High (ACID)&lt;/td&gt;
&lt;td&gt;Varies (configurable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Included in DB&lt;/td&gt;
&lt;td&gt;Additional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Good for moderate loads&lt;/td&gt;
&lt;td&gt;Excellent for high loads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;See the &lt;a href="https://www.postgresql.org/docs/current/transaction-iso.html" rel="noopener noreferrer"&gt;PostgreSQL documentation on transactions&lt;/a&gt; for more on ACID properties.&lt;/p&gt;
&lt;h2&gt;
  
  
  Preparing Your PostgreSQL Environment
&lt;/h2&gt;

&lt;p&gt;Start by ensuring PostgreSQL is installed and running. Use version 14 or later for better performance features like improved indexing.&lt;/p&gt;

&lt;p&gt;Create a database for your queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;task_queue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Connect to it and enable necessary extensions if needed, though for basic queues, the core features suffice.&lt;/p&gt;

&lt;p&gt;In Go, you'll need the &lt;code&gt;lib/pq&lt;/code&gt; driver. Install it with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/lib/pq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Set up your connection string, like &lt;code&gt;postgres://user:pass@localhost:5432/task_queue?sslmode=disable&lt;/code&gt;. Always handle connections with a pool for efficiency.&lt;/p&gt;

&lt;p&gt;Test your setup with a simple query to confirm connectivity.&lt;/p&gt;
&lt;h2&gt;
  
  
  Designing the Queue Table Schema
&lt;/h2&gt;

&lt;p&gt;The core of your queue is a table to store tasks. Include columns for task ID, payload, status, and timestamps.&lt;/p&gt;

&lt;p&gt;Here's a sample schema:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_attempt_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_status&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;payload&lt;/strong&gt;: Stores task data as JSONB for flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;status&lt;/strong&gt;: Tracks states like 'pending', 'processing', 'failed', 'done'.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;attempts&lt;/strong&gt;: Counts retries for failure handling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The index on status speeds up queries for pending tasks. This design supports easy querying and updates.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enqueuing Tasks from Go Code
&lt;/h2&gt;

&lt;p&gt;To add tasks, insert rows into the table. Use Go's &lt;code&gt;database/sql&lt;/code&gt; package for this.&lt;/p&gt;

&lt;p&gt;Here's a complete example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"database/sql"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"github.com/lib/pq"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"postgres://user:pass@localhost:5432/task_queue?sslmode=disable"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"action"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"send_email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"to"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"user@example.com"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;payloadBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"INSERT INTO tasks (payload) VALUES ($1)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payloadBytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task enqueued successfully"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Output: Task enqueued successfully&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This code connects, marshals a JSON payload, and inserts it. Run it after setting up the table; it should add a row without errors.&lt;/p&gt;

&lt;p&gt;Wrap enqueuing in transactions if it depends on other operations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dequeuing and Processing Tasks Efficiently
&lt;/h2&gt;

&lt;p&gt;Dequeuing involves selecting a pending task, marking it as processing, and handling it. Use &lt;code&gt;FOR UPDATE SKIP LOCKED&lt;/code&gt; to avoid blocking multiple workers.&lt;/p&gt;

&lt;p&gt;Example worker code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"database/sql"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"github.com/lib/pq"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;      &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;Payload&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"postgres://user:pass@localhost:5432/task_queue?sslmode=disable"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;payloadBytes&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`SELECT id, payload FROM tasks 
            WHERE status = 'pending' 
            ORDER BY created_at ASC 
            FOR UPDATE SKIP LOCKED 
            LIMIT 1`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;payloadBytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrNoRows&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE tasks SET status = 'processing', last_attempt_at = CURRENT_TIMESTAMP WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payloadBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;// Process the task here, e.g., send email based on payload["action"]&lt;/span&gt;

        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE tasks SET status = 'done' WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processed task %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;// Example output: Processed task 1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This loop polls for tasks, locks one, processes it, and updates status. The &lt;code&gt;SKIP LOCKED&lt;/code&gt; allows multiple workers to run concurrently without conflicts.&lt;/p&gt;

&lt;p&gt;For more on row locking, check &lt;a href="https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE" rel="noopener noreferrer"&gt;PostgreSQL's SELECT FOR UPDATE docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementing Retry Logic for Failed Tasks
&lt;/h2&gt;

&lt;p&gt;Failures happen, so build in retries. Update attempts on error and reset status after max attempts.&lt;/p&gt;

&lt;p&gt;Modify the dequeue code to handle failures:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Add this inside the processing block, after unmarshal&lt;/span&gt;

&lt;span class="c"&gt;// Simulate processing&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"send_email"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Imagine email sending code here&lt;/span&gt;
    &lt;span class="c"&gt;// If fails:&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"simulated failure"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="c"&gt;// Fetch actual attempts from query&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// Max retries&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE tasks SET status = 'failed' WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE tasks SET status = 'pending', attempts = attempts + 1 WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE tasks SET status = 'done' WHERE id = $1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Query attempts in the select:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This retries up to 3 times, marking as failed afterward. Adjust based on your needs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scaling with Multiple Workers and Notifications
&lt;/h2&gt;

&lt;p&gt;For higher throughput, run multiple Go workers. Each polls independently thanks to SKIP LOCKED.&lt;/p&gt;

&lt;p&gt;To reduce polling overhead, use PostgreSQL's LISTEN/NOTIFY. Notify on enqueue, and workers listen for events.&lt;/p&gt;

&lt;p&gt;Setup in PostgreSQL:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- On enqueue, after INSERT:&lt;/span&gt;
&lt;span class="k"&gt;NOTIFY&lt;/span&gt; &lt;span class="n"&gt;new_task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In Go, use &lt;code&gt;pq.Listener&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/lib/pq"&lt;/span&gt;

&lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pq&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Minute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="n"&gt;pq&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenerEventType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"new_task"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Notify&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// Dequeue and process&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;90&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// Check anyway&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This wakes workers on new tasks, saving CPU. See &lt;a href="https://pkg.go.dev/github.com/lib/pq" rel="noopener noreferrer"&gt;pq library docs&lt;/a&gt; for full listener usage.&lt;/p&gt;
&lt;h2&gt;
  
  
  Optimizing Performance for Larger Workloads
&lt;/h2&gt;

&lt;p&gt;Monitor query performance with EXPLAIN ANALYZE on your SELECTs.&lt;/p&gt;

&lt;p&gt;Add vacuuming for the table:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;VACUUM&lt;/span&gt; &lt;span class="k"&gt;ANALYZE&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For very large queues, partition the table by status or date.&lt;/p&gt;

&lt;p&gt;Use connection pooling in Go with &lt;code&gt;sql.DB&lt;/code&gt; defaults, and set &lt;code&gt;MaxOpenConnections&lt;/code&gt; to match your DB capacity.&lt;/p&gt;

&lt;p&gt;Benchmark your setup: Insert 1000 tasks and measure pprocessing time. Aim for under 10ms per task in low-load scenarios.&lt;/p&gt;

&lt;p&gt;If queues grow too large, archive done tasks to a separate table periodically.&lt;/p&gt;

&lt;p&gt;This PostgreSQL-based queue in Go provides a reliable, low-overhead solution for many applications. It handles failures gracefully and scales with your database. Experiment with these patterns in your projects to see where they fit best, and consider monitoring tools like pg_stat_statements for ongoing tweaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>go</category>
    </item>
    <item>
      <title>Advanced AWS S3 Management: Mastering Instance Tiers and Lifecycle Controls</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Fri, 19 Sep 2025 17:45:48 +0000</pubDate>
      <link>https://dev.to/shrsv/advanced-aws-s3-management-mastering-instance-tiers-and-lifecycle-controls-1olk</link>
      <guid>https://dev.to/shrsv/advanced-aws-s3-management-mastering-instance-tiers-and-lifecycle-controls-1olk</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;AWS offers tools to run workloads efficiently without wasting resources. EC2 instance tiers let you pick hardware that fits your app's needs, while lifecycle methods automate scaling and storage transitions. This post dives into how to use them effectively, with code examples you can run.
&lt;h2&gt;
  
  
  Decoding EC2 Instance Families for Optimal Performance
&lt;/h2&gt;

&lt;p&gt;EC2 instances come in families optimized for specific workloads. General-purpose like M7 suit balanced apps, compute-optimized C7 handle high CPU tasks, and memory-optimized R8 manage large datasets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Match family to workload to avoid overprovisioning. For a web app with steady traffic, start with M6g (Graviton-based for cost savings).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Family&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Example Instance&lt;/th&gt;
&lt;th&gt;vCPU/Memory Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;M (General)&lt;/td&gt;
&lt;td&gt;Web servers, databases&lt;/td&gt;
&lt;td&gt;m7g.large&lt;/td&gt;
&lt;td&gt;2 vCPU, 8 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C (Compute)&lt;/td&gt;
&lt;td&gt;Batch processing&lt;/td&gt;
&lt;td&gt;c7g.xlarge&lt;/td&gt;
&lt;td&gt;4 vCPU, 8 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R (Memory)&lt;/td&gt;
&lt;td&gt;In-memory caches&lt;/td&gt;
&lt;td&gt;r8g.2xlarge&lt;/td&gt;
&lt;td&gt;8 vCPU, 64 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test with AWS Compute Optimizer for recommendations. For details, see the &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html" rel="noopener noreferrer"&gt;EC2 Instance Types guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Selecting the Right Instance Size Without Guesswork
&lt;/h2&gt;

&lt;p&gt;Instance sizes scale within families: .micro for testing, .xlarge for production. Names like t3.micro indicate burstable performance for variable loads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Use burstable T4g for dev environments to earn credits during low use and burst when needed.&lt;/p&gt;

&lt;p&gt;Launch a t3.micro via AWS CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 run-instances &lt;span class="nt"&gt;--image-id&lt;/span&gt; ami-0abcdef1234567890 &lt;span class="nt"&gt;--count&lt;/span&gt; 1 &lt;span class="nt"&gt;--instance-type&lt;/span&gt; t3.micro &lt;span class="nt"&gt;--key-name&lt;/span&gt; MyKeyPair
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This starts a free-tier eligible instance. Monitor CPU credits with CloudWatch; if credits deplete often, upgrade to non-burstable like m5.&lt;/p&gt;
&lt;h2&gt;
  
  
  Leveraging Pricing Tiers to Slash Compute Costs
&lt;/h2&gt;

&lt;p&gt;AWS pricing tiers include On-Demand for flexibility, Reserved for steady workloads (up to 72% savings), and Spot for interruptible tasks (up to 90% off).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Commit to Savings Plans for flexibility across families. Analyze usage with Cost Explorer first.&lt;/p&gt;

&lt;p&gt;For a predictable app, buy a 1-year Reserved m5.large: savings apply automatically. Spot example for batch jobs:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 request-spot-instances &lt;span class="nt"&gt;--spot-price&lt;/span&gt; &lt;span class="s2"&gt;"0.01"&lt;/span&gt; &lt;span class="nt"&gt;--instance-count&lt;/span&gt; 1 &lt;span class="nt"&gt;--launch-specification&lt;/span&gt; &lt;span class="s1"&gt;'{"ImageId":"ami-0abcdef1234567890","InstanceType":"c5.large"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output: Spot request ID. Instances launch if bid wins; use for non-critical workloads like data processing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Automating EC2 Scaling with Lifecycle Hooks
&lt;/h2&gt;

&lt;p&gt;Lifecycle hooks pause instances during launch or termination for custom actions, like installing software or backing up data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Hooks integrate with Lambda for serverless automation. Default timeout is 1 hour; extend with heartbeats.&lt;/p&gt;

&lt;p&gt;Create a launch hook via CLI:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws autoscaling put-lifecycle-hook &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lifecycle-hook-name&lt;/span&gt; my-launch-hook &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auto-scaling-group-name&lt;/span&gt; my-asg &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lifecycle-transition&lt;/span&gt; autoscaling:EC2_INSTANCE_LAUNCHING &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--heartbeat-timeout&lt;/span&gt; 300 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--default-result&lt;/span&gt; CONTINUE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This pauses new instances for 5 minutes. Pair with EventBridge to trigger Lambda for setup. For termination, swap to EC2_INSTANCE_TERMINATING to drain connections. See &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html" rel="noopener noreferrer"&gt;lifecycle hooks docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Streamlining S3 Storage with Lifecycle Policies
&lt;/h2&gt;

&lt;p&gt;S3 lifecycle policies transition objects between classes: Standard for hot data, IA for infrequent, Glacier for archives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Automate to cut costs; e.g., move logs to IA after 30 days.&lt;/p&gt;

&lt;p&gt;Apply a policy via CLI (save as lifecycle.json first):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TransitionToIA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enabled"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Transitions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"StorageClass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"STANDARD_IA"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-lifecycle-configuration &lt;span class="nt"&gt;--bucket&lt;/span&gt; my-bucket &lt;span class="nt"&gt;--lifecycle-configuration&lt;/span&gt; file://lifecycle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After 30 days, logs move to IA; after 365, delete. No output on success; verify with &lt;code&gt;aws s3api get-bucket-lifecycle-configuration&lt;/code&gt;. For more, check &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html" rel="noopener noreferrer"&gt;S3 lifecycle management&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Integrating Hooks and Policies for Seamless Operations
&lt;/h2&gt;

&lt;p&gt;Combine EC2 hooks with S3 policies: use termination hooks to upload final logs to S3 before delete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; In a hook Lambda, sync data then complete the action.&lt;/p&gt;

&lt;p&gt;Example Lambda (Python, deploy via console):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ec2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ec2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;instance_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Detail&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EC2InstanceId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Run command to backup logs
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;InstanceIds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;instance_id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;DocumentName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AWS-RunShellScript&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;commands&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;aws s3 sync /var/log/ s3://my-bucket/backups/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Complete lifecycle
&lt;/span&gt;    &lt;span class="n"&gt;autoscaling&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;autoscaling&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;autoscaling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete_lifecycle_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;LifecycleHookName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-termination-hook&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;AutoScalingGroupName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-asg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;LifecycleActionToken&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Detail&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LifecycleActionToken&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;LifecycleActionResult&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CONTINUE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This syncs logs, then proceeds termination. Test in a dev ASG; output: 200 on success.&lt;/p&gt;
&lt;h2&gt;
  
  
  Monitoring and Fine-Tuning for Long-Term Efficiency
&lt;/h2&gt;

&lt;p&gt;Use CloudWatch for metrics like CPU utilization and S3 access patterns. Set alarms for low credits or high costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key point:&lt;/strong&gt; Review monthly with Cost Explorer; adjust tiers based on data.&lt;/p&gt;

&lt;p&gt;For S3, enable Storage Class Analysis to recommend transitions. Script a check:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-analytics-configuration &lt;span class="nt"&gt;--bucket&lt;/span&gt; my-bucket &lt;span class="nt"&gt;--id&lt;/span&gt; my-analysis &lt;span class="nt"&gt;--analytics-configuration&lt;/span&gt; &lt;span class="s1"&gt;'{"Id":"my-analysis","StorageClassAnalysis":{"DataExport":"{"Destination":{"S3BucketDestination":{"Format":"CSV","BucketAccountId":"123456789012","Bucket":"my-results-bucket","Prefix":"analysis/"}}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generates reports in another bucket. Optimize by acting on infrequent access insights.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building Resilient Workloads with Tiered Strategies
&lt;/h2&gt;

&lt;p&gt;Apply these in layers: choose Graviton instances for ARM-compatible apps to save 20% on compute. For storage, default uploads to Intelligent-Tiering for auto-optimization.&lt;/p&gt;

&lt;p&gt;Test in sandbox: Launch ASG with hooks, upload to S3 with policy, monitor costs. Scale to production for real savings. Regularly audit to adapt to changing patterns, ensuring apps run lean and reliable.# Mastering AWS Efficiency: Tiers, Lifecycle Policies, and Beyond&lt;/p&gt;

&lt;p&gt;AWS offers a vast array of services, but costs can spiral if you don't manage them right. Developers often overlook the built-in tools for optimization, leading to unexpected bills. This post dives into key strategies like pricing tiers, lifecycle methods, and more, with practical examples to help you trim fat without sacrificing performance.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why AWS Tiers Matter for Your Workloads
&lt;/h2&gt;

&lt;p&gt;AWS pricing tiers let you pay based on usage patterns, from on-demand flexibility to long-term commitments. Start with &lt;strong&gt;On-Demand Instances&lt;/strong&gt; for sporadic tasks—they charge per second but offer no discounts. For steady workloads, &lt;strong&gt;Reserved Instances&lt;/strong&gt; lock in lower rates for 1-3 years, saving up to 75%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Savings Plans&lt;/strong&gt; provide more flexibility, applying discounts across instance families or services like Lambda. Choose Compute Savings Plans for broad coverage or EC2 Instance Savings Plans for specific types.&lt;/p&gt;

&lt;p&gt;Here's a quick comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier Type&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Savings Potential&lt;/th&gt;
&lt;th&gt;Commitment Level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;On-Demand&lt;/td&gt;
&lt;td&gt;Testing, variable loads&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reserved Instances&lt;/td&gt;
&lt;td&gt;Predictable EC2 usage&lt;/td&gt;
&lt;td&gt;Up to 75%&lt;/td&gt;
&lt;td&gt;1-3 years&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Savings Plans&lt;/td&gt;
&lt;td&gt;Flexible across services&lt;/td&gt;
&lt;td&gt;Up to 72%&lt;/td&gt;
&lt;td&gt;1-3 years&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To check your eligibility, use the AWS Pricing Calculator. For deeper dives, see the &lt;a href="https://docs.aws.amazon.com/savingsplans/latest/userguide/what-is-savings-plans.html" rel="noopener noreferrer"&gt;AWS Savings Plans documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reserved Instances: Lock In Savings for Steady Apps
&lt;/h2&gt;

&lt;p&gt;Reserved Instances (RIs) are ideal for apps running 24/7, like databases or web servers. You buy capacity upfront, reducing hourly rates.&lt;/p&gt;

&lt;p&gt;Example: Launch an m5.large instance on-demand at $0.096/hour. With a 1-year no-upfront RI, it drops to $0.064/hour—a 33% cut.&lt;/p&gt;

&lt;p&gt;To purchase via CLI:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install AWS CLI if needed, then configure with 'aws configure'&lt;/span&gt;
aws ec2 purchase-reserved-instances-offering &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--instance-count&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--offering-id&lt;/span&gt; abc123def456 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--reserved-instances-offering-id&lt;/span&gt; r-1234567890abcdef0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output (simplified):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "ReservedInstancesId": "r-1234567890abcdef0"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This returns the RI ID. Monitor usage in the EC2 console to avoid underutilization—aim for 80% coverage.&lt;/p&gt;
&lt;h2&gt;
  
  
  Savings Plans: Flexibility Without the Lock-In
&lt;/h2&gt;

&lt;p&gt;Unlike RIs, Savings Plans apply discounts automatically to matching usage. Compute Savings Plans cover EC2, Lambda, and Fargate; EC2 Instance Savings Plans stick to specific families.&lt;/p&gt;

&lt;p&gt;For a Node.js app on Lambda, commit to $10/hour for 1 year at 66% savings. Overages fall back to on-demand.&lt;/p&gt;

&lt;p&gt;Python example using boto3 to view recommendations:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;savingsplans_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;savingsplans&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;savingsplans_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_savings_plan_purchase_recommendation_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;values&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Lambda&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recommendations&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recommendationSummary&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output comment: Prints summary like {'EstimatedSavingsAmount': '150.00', 'HourlyCommitmentToPurchase': '5.00'}—adjust based on your account.&lt;/p&gt;

&lt;p&gt;This tool suggests optimal commitments. Track via Cost Explorer for real impact.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lifecycle Policies: Automate S3 Cost Control
&lt;/h2&gt;

&lt;p&gt;S3 Lifecycle policies transition objects between storage classes or delete them to cut costs. Infrequent Access (IA) saves 40% over Standard, Glacier up to 90%.&lt;/p&gt;

&lt;p&gt;Set a policy to move logs older than 30 days to IA.&lt;/p&gt;

&lt;p&gt;Console steps: In S3 bucket &amp;gt; Management &amp;gt; Create lifecycle rule. Or via SDK:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;s3_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_bucket_lifecycle_configuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-log-bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LifecycleConfiguration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Rules&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ID&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LogTransition&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Enabled&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Filter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Prefix&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;logs/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Transitions&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;StorageClass&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;STANDARD_IA&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Expiration&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No direct output—this configures the bucket. Verify in console; objects transition automatically, reducing bills.&lt;/p&gt;

&lt;p&gt;Use this for dev artifacts—keeps storage lean.&lt;/p&gt;
&lt;h2&gt;
  
  
  Spot Instances: Slash Costs for Non-Critical Tasks
&lt;/h2&gt;

&lt;p&gt;Spot Instances bid on spare EC2 capacity at up to 90% off, but can interrupt with 2-minute notice. Perfect for CI/CD, data processing, or batch jobs.&lt;/p&gt;

&lt;p&gt;Handle interruptions in code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python script for Spot request with interruption handler
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;ec2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ec2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request_spot_instances&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;SpotPrice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.01&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;InstanceCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LaunchSpecification&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ImageId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ami-12345678&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;InstanceType&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;m5.large&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;KeyName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;spot_request_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SpotInstanceRequests&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SpotInstanceRequestId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Poll for state
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe_spot_instance_requests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SpotInstanceRequestIds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;spot_request_id&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SpotInstanceRequests&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;State&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;closed&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;State: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output comment: Prints "State: active" if fulfilled, or "closed" if interrupted. Use checkpoints for resumable jobs.&lt;/p&gt;

&lt;p&gt;Diversify instance types to minimize interruptions.&lt;/p&gt;
&lt;h2&gt;
  
  
  EC2 Lifecycle Hooks: Graceful Instance Management
&lt;/h2&gt;

&lt;p&gt;In Auto Scaling Groups (ASGs), lifecycle hooks pause scaling for custom actions like draining connections.&lt;/p&gt;

&lt;p&gt;Hook example: On termination, notify Lambda to snapshot EBS.&lt;/p&gt;

&lt;p&gt;Terraform snippet (complete, run with &lt;code&gt;terraform apply&lt;/code&gt; after init):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_autoscaling_lifecycle_hook"&lt;/span&gt; &lt;span class="s2"&gt;"terminate_hook"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terminate-hook"&lt;/span&gt;
  &lt;span class="nx"&gt;autoscaling_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_autoscaling_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;default_result&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CONTINUE"&lt;/span&gt;
  &lt;span class="nx"&gt;heartbeat_timeout&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
  &lt;span class="nx"&gt;lifecycle_transition&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"autoscaling:EC2_INSTANCE_TERMINATING"&lt;/span&gt;

  &lt;span class="nx"&gt;notification_target_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_sns_topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;role_arn&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Simplified supporting resources&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_sns_topic"&lt;/span&gt; &lt;span class="s2"&gt;"hook"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"asg-hook"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"hook"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"autoscaling.amazonaws.com"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output: Creates hook; test by scaling down ASG—hook triggers SNS.&lt;/p&gt;

&lt;p&gt;This prevents data loss in scaling events.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cost Explorer and Budgets: Track and Alert on Spend
&lt;/h2&gt;

&lt;p&gt;AWS Cost Explorer visualizes bills by service or tag. Set budgets with alerts for thresholds.&lt;/p&gt;

&lt;p&gt;Example: Budget for EC2 under $100/month.&lt;/p&gt;

&lt;p&gt;CLI to create:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws budgets create-budget &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--account-id&lt;/span&gt; 123456789012 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--budget&lt;/span&gt; &lt;span class="s1"&gt;'{
        "BudgetName": "EC2Budget",
        "BudgetLimit": {"Amount": "100", "Unit": "USD"},
        "BudgetType": "COST",
        "TimeUnit": "MONTHLY",
        "CostFilters": {"Service": ["Amazon Elastic Compute Cloud - Compute"]},
        "Notification": {
            "ComparisonOperator": "GREATER_THAN",
            "Threshold": 100,
            "ThresholdType": "PERCENTAGE"
        }
    }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Budget": { "BudgetName": "EC2Budget" }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Emails alert at 100%—review in console for anomalies.&lt;/p&gt;

&lt;p&gt;Tag resources consistently for granular views.&lt;/p&gt;
&lt;h2&gt;
  
  
  Multi-Account Strategies with Organizations
&lt;/h2&gt;

&lt;p&gt;AWS Organizations centralize management across accounts. Use consolidated billing for volume discounts and SCPs to enforce policies.&lt;/p&gt;

&lt;p&gt;Separate dev/prod accounts to isolate costs. Enable Cost Explorer at org level.&lt;/p&gt;

&lt;p&gt;Quick setup via CLI:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws organizations create-organization &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--feature-set&lt;/span&gt; ALL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Organization": {
        "Id": "o-1234567890",
        "FeatureSet": "ALL"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This creates the org—invite accounts next. Apply budgets org-wide to cap total spend.&lt;/p&gt;
&lt;h2&gt;
  
  
  Putting It All Together for Sustainable AWS Use
&lt;/h2&gt;

&lt;p&gt;Combine these tools: Use Savings Plans for core workloads, Spot for bursts, and lifecycle policies everywhere. Regularly audit with Cost Explorer, and scale via Organizations as your team grows. Start small—apply one change per project—and watch bills drop 30-50%. Experiment in a sandbox account to test without risk, ensuring your AWS setup scales efficiently with your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>aws</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>performance</category>
    </item>
    <item>
      <title>Postfix vs. Dovecot: Key Differences for Building Email Systems</title>
      <dc:creator>Shrijith Venkatramana</dc:creator>
      <pubDate>Thu, 18 Sep 2025 17:18:00 +0000</pubDate>
      <link>https://dev.to/shrsv/postfix-vs-dovecot-key-differences-for-building-email-systems-55k2</link>
      <guid>https://dev.to/shrsv/postfix-vs-dovecot-key-differences-for-building-email-systems-55k2</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt;Postfix and Dovecot are two essential open-source tools in the world of email servers. Developers often encounter them when setting 

&lt;p&gt;Let me know if you have any other text you'd like me to clean!up mail infrastructure for applications or self-hosted services. While they both deal with email, they serve distinct purposes. This post breaks down their differences with practical details and examples to help you decide how to use them—or combine them—in your projects.&lt;/p&gt;
&lt;h2&gt;
  
  
  Postfix as the Mail Transfer Agent
&lt;/h2&gt;

&lt;p&gt;Postfix acts as the backbone for sending and receiving emails between servers. It functions as a Mail Transfer Agent (MTA), handling the SMTP protocol to route messages reliably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key role&lt;/strong&gt;: Postfix queues incoming and outgoing emails, ensures delivery to other MTAs, and filters spam at the transport level. It's designed for high throughput and security, replacing older systems like Sendmail.&lt;/p&gt;

&lt;p&gt;In a typical setup, Postfix listens on port 25 for incoming SMTP connections. It processes emails from clients or other servers, stores them temporarily in queues, and forwards them to destinations.&lt;/p&gt;

&lt;p&gt;For example, if you're building a web app that sends notifications, Postfix can relay those emails without exposing your app directly to the internet.&lt;/p&gt;

&lt;p&gt;Official Postfix documentation: &lt;a href="http://www.postfix.org/OVERVIEW.html" rel="noopener noreferrer"&gt;Postfix Overview&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Dovecot's Focus on Email Retrieval
&lt;/h2&gt;

&lt;p&gt;Dovecot is built for client access to emails, serving as an IMAP and POP3 server. It allows users to fetch, organize, and manage messages stored on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key role&lt;/strong&gt;: Dovecot provides secure protocols like IMAP (for folder syncing) and POP3 (for downloading). It doesn't handle sending; instead, it authenticates users and delivers stored emails to clients like Thunderbird or Outlook.&lt;/p&gt;

&lt;p&gt;Dovecot supports Maildir and mbox formats for storage, making it flexible for different setups. It's lightweight and excels in handling multiple concurrent connections from email clients.&lt;/p&gt;

&lt;p&gt;If your project involves user inboxes, Dovecot ensures seamless access without the overhead of full MTA duties.&lt;/p&gt;
&lt;h2&gt;
  
  
  Core Functional Differences
&lt;/h2&gt;

&lt;p&gt;The main split between Postfix and Dovecot lies in their scope: transport versus access.&lt;/p&gt;

&lt;p&gt;Postfix manages the "delivery highway" for emails, while Dovecot handles the "mailbox interface" for end-users.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Postfix&lt;/th&gt;
&lt;th&gt;Dovecot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary Protocol&lt;/td&gt;
&lt;td&gt;SMTP (port 25/587)&lt;/td&gt;
&lt;td&gt;IMAP (port 143/993), POP3 (110/995)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main Task&lt;/td&gt;
&lt;td&gt;Routing and queuing emails&lt;/td&gt;
&lt;td&gt;Retrieving and managing emails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Interaction&lt;/td&gt;
&lt;td&gt;Server-to-server or submission&lt;/td&gt;
&lt;td&gt;Client-to-server access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Role&lt;/td&gt;
&lt;td&gt;Temporary queues&lt;/td&gt;
&lt;td&gt;Persistent mailbox access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This table highlights why they're not interchangeable—Postfix can't serve IMAP, and Dovecot doesn't route emails.&lt;/p&gt;
&lt;h2&gt;
  
  
  How Postfix Routes Emails Step by Step
&lt;/h2&gt;

&lt;p&gt;Postfix processes emails in a modular way. When an email arrives via SMTP, it goes through several stages: reception, queuing, and delivery.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reception&lt;/strong&gt;: Postfix's smtpd daemon accepts connections and verifies senders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queuing&lt;/strong&gt;: Emails land in the incoming queue, then active queue for processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delivery&lt;/strong&gt;: The qmgr process routes to local mailboxes or remote servers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Consider this simple Postfix config snippet for a basic relay setup. Save it as &lt;code&gt;/etc/postfix/main.cf&lt;/code&gt; and run &lt;code&gt;postfix reload&lt;/code&gt; to apply. This enables TLS for secure submission.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/postfix/main.cf
smtpd_tls_cert_file = /etc/ssl/certs/server.crt
smtpd_tls_key_file = /etc/ssl/private/server.key
smtpd_use_tls = yes
submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After reloading, test with &lt;code&gt;telnet localhost 587&lt;/code&gt; and issue &lt;code&gt;EHLO test&lt;/code&gt;, followed by auth commands. Output: Successful connection with TLS enabled, as shown in logs via &lt;code&gt;tail -f /var/log/maillog&lt;/code&gt; (expect "smtpd: connect from localhost").&lt;/p&gt;

&lt;p&gt;This setup routes emails securely but requires SASL for auth—pair it with tools like Cyrus SASL.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dovecot's Approach to Mailbox Access
&lt;/h2&gt;

&lt;p&gt;Dovecot emphasizes efficiency in serving emails. It uses a plugin-based architecture for features like quotas and indexing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt;: Integrates with PAM or LDAP to verify users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delivery&lt;/strong&gt;: Via LMTP, it stores emails from Postfix into user mailboxes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access&lt;/strong&gt;: Clients connect via IMAP to search and sync folders.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's a basic Dovecot config for IMAP with Maildir storage. Place in &lt;code&gt;/etc/dovecot/dovecot.conf&lt;/code&gt; and restart with &lt;code&gt;systemctl restart dovecot&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/dovecot/dovecot.conf
mail_location = maildir:~/Maildir
protocols = imap pop3
mail_privileged_group = mail
ssl = required
ssl_cert = &amp;lt;/etc/ssl/certs/server.crt
ssl_key = &amp;lt;/etc/ssl/private/server.key
auth_mechanisms = plain login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Test by connecting with &lt;code&gt;telnet localhost 143&lt;/code&gt;, then &lt;code&gt;a LOGIN user password&lt;/code&gt;. Output: "a OK Logged in" if credentials match. Use &lt;code&gt;openssl s_client -connect localhost:993&lt;/code&gt; for secure IMAP; expect a successful handshake.&lt;/p&gt;

&lt;p&gt;This config supports basic access—add &lt;code&gt;!include auth-sql.conf.ext&lt;/code&gt; for database-backed users.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuration Challenges and Best Practices
&lt;/h2&gt;

&lt;p&gt;Configuring Postfix involves tuning queues and anti-spam rules, while Dovecot focuses on auth and storage backends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bold tip&lt;/strong&gt;: Always enable TLS in both to avoid plaintext leaks. Postfix uses &lt;code&gt;smtpd_tls_security_level=may&lt;/code&gt;, Dovecot sets &lt;code&gt;ssl=yes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Common pitfalls: Mismatched user mappings between tools. Use virtual domains in Postfix (&lt;code&gt;virtual_alias_maps&lt;/code&gt;) to align with Dovecot's userdb.&lt;/p&gt;

&lt;p&gt;For a dev project, start with Docker images: &lt;code&gt;docker run -p 25:25 postfix&lt;/code&gt; for quick testing, but customize volumes for persistence.&lt;/p&gt;

&lt;p&gt;Link to a config guide: &lt;a href="https://doc.dovecot.org/configuration_manual/quickguide/" rel="noopener noreferrer"&gt;Dovecot Configuration Primer&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Performance Tuning for High Loads
&lt;/h2&gt;

&lt;p&gt;Postfix scales via process limits and queue management, handling thousands of emails per minute out of the box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key metrics&lt;/strong&gt;: Tune &lt;code&gt;default_process_limit&lt;/code&gt; (default 100) in main.cf for concurrency. Monitor with &lt;code&gt;postqueue -p&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dovecot shines in low-latency access, using index files to speed up searches. Set &lt;code&gt;maildir_copy_with_hardlinks=yes&lt;/code&gt; for faster ops.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Postfix Optimization&lt;/th&gt;
&lt;th&gt;Dovecot Optimization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;td&gt;Increase smtp_destination_concurrency_limit&lt;/td&gt;
&lt;td&gt;Use lazy_expunge for deletes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory Use&lt;/td&gt;
&lt;td&gt;qmgr limits processes&lt;/td&gt;
&lt;td&gt;mmaps files for indexing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU Load&lt;/td&gt;
&lt;td&gt;Spam filtering via policyd&lt;/td&gt;
&lt;td&gt;Plugin disabling for light setups&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In benchmarks, Postfix delivers 10k emails/hour on modest hardware; Dovecot handles 500+ IMAP sessions similarly.&lt;/p&gt;

&lt;p&gt;Example: For Postfix, add to main.cf: &lt;code&gt;default_process_limit = 200&lt;/code&gt;. Reload and stress-test with &lt;code&gt;swaks --to test@example.com --server localhost&lt;/code&gt;. Output: Faster delivery times in logs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Security Features Compared
&lt;/h2&gt;

&lt;p&gt;Both tools prioritize security, but in different areas.&lt;/p&gt;

&lt;p&gt;Postfix blocks unauthorized relays with &lt;code&gt;smtpd_recipient_restrictions&lt;/code&gt; and integrates with SpamAssassin.&lt;/p&gt;

&lt;p&gt;Dovecot enforces auth via mechanisms like DIGEST-MD5 and supports SELinux for file protection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bold point&lt;/strong&gt;: Postfix prevents spam injection; Dovecot guards against unauthorized mailbox reads.&lt;/p&gt;

&lt;p&gt;Enable Postfix's &lt;code&gt;smtpd_helo_restrictions = reject_non_fqdn_helo&lt;/code&gt; to filter bad clients. For Dovecot, use &lt;code&gt;disable_plaintext_auth = yes&lt;/code&gt; to force encryption.&lt;/p&gt;

&lt;p&gt;In a secure setup, combine with Fail2Ban for brute-force protection.&lt;/p&gt;
&lt;h2&gt;
  
  
  Integrating Postfix and Dovecot for Full Mail Service
&lt;/h2&gt;

&lt;p&gt;These tools complement each other perfectly. Postfix delivers to local mailboxes via Dovecot's LMTP (port 24).&lt;/p&gt;

&lt;p&gt;Setup flow: Install both on Ubuntu with &lt;code&gt;apt install postfix dovecot-core dovecot-imapd&lt;/code&gt;. Configure Postfix's &lt;code&gt;transport_maps&lt;/code&gt; to point to &lt;code&gt;lmtp:unix:/var/run/dovecot/lmtp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example alias in &lt;code&gt;/etc/aliases&lt;/code&gt;: &lt;code&gt;dev: /home/dev/Maildir&lt;/code&gt;. Run &lt;code&gt;newaliases&lt;/code&gt; and &lt;code&gt;postfix reload&lt;/code&gt;. Send a test email: &lt;code&gt;echo "Test" | mail -s "Subject" dev@localhost&lt;/code&gt;. Check inbox with IMAP client—email appears in Maildir.&lt;/p&gt;

&lt;p&gt;This integration creates a complete server: Postfix for in/out,Dovecot for access. Logs in &lt;code&gt;/var/log/mail.log&lt;/code&gt; confirm delivery.&lt;/p&gt;

&lt;p&gt;For alternatives, consider iRedMail for bundled installs, but understanding the duo gives you control.&lt;/p&gt;

&lt;p&gt;When setting up email for apps, lean on Postfix for reliable sending and Dovecot for user-facing retrieval. Their differences make them ideal partners, reducing complexity in custom stacks. Experiment with configs on a VM to see how they fit your needs, and scale as your project grows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
