<?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: Saul Fernandez</title>
    <description>The latest articles on DEV Community by Saul Fernandez (@sarony11).</description>
    <link>https://dev.to/sarony11</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F399348%2F2df84a4d-b364-415f-9944-4b51cc1c8fe2.jpeg</url>
      <title>DEV Community: Saul Fernandez</title>
      <link>https://dev.to/sarony11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sarony11"/>
    <language>en</language>
    <item>
      <title>How I Slashed My AI Agent Token Costs by 90% (And Survived a Multi-Provider Docker Nightmare)</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Thu, 09 Jul 2026 17:55:45 +0000</pubDate>
      <link>https://dev.to/sarony11/how-i-slashed-my-ai-agent-token-costs-by-90-and-survived-a-multi-provider-docker-nightmare-1cgj</link>
      <guid>https://dev.to/sarony11/how-i-slashed-my-ai-agent-token-costs-by-90-and-survived-a-multi-provider-docker-nightmare-1cgj</guid>
      <description>&lt;p&gt;My autonomous coding agent setup in Discord was running beautifully, but my monthly token bill was starting to look like a phone number. Every time my agent read a git diff, examined a database structure, or ran a deep directory search, it dumped thousands of lines of raw text into the conversation history. Since coding agents operate in multi-turn loops, reading this accumulated "context bloat" over and over quickly became incredibly slow and expensive.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;a href="https://github.com/headroomlabs-ai/headroom" rel="noopener noreferrer"&gt;Headroom AI&lt;/a&gt;, an open-source tool designed to shrink agent prompt context by 60% to 95% using content-aware compressors (like Tree-sitter for code ASTs and SmartCrusher for JSON).&lt;/p&gt;

&lt;p&gt;It sounded perfect. But when I tried to deploy it as a standard local proxy in my Docker Compose stack, I ran into a wall of TCP connection resets, 401 authentication errors, and broken tool calls.&lt;/p&gt;

&lt;p&gt;This is the story of how I resolved those network bottlenecks, bypassed a frustrating GitHub Copilot gateway bug, and wrote a lightweight in-process TypeScript middleware to get Headroom running with 100% stability and massive cost savings.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Initial Plan (And Why My Sockets Blew Up)
&lt;/h2&gt;

&lt;p&gt;The standard integration path for Headroom is running its container as a local proxy on port 8787. You then configure your coding agent to point its OpenAI and Anthropic base URLs to this proxy.&lt;/p&gt;

&lt;p&gt;But in my multi-provider setup—where my agent dynamically switches between Google Gemini, Claude, DeepSeek, and Copilot within the same thread—this naive approach broke instantly.&lt;/p&gt;

&lt;p&gt;First, I hit a classic network timing race condition. I configured my agent's container to share its network namespace with the Headroom container (&lt;code&gt;network_mode: "service:agent"&lt;/code&gt;). During stack boot-up, Headroom tried to bind to port 8787 before the agent container had fully initialized the shared interface. My agent started up, couldn't reach the proxy on localhost, and fell back to uncompressed direct routes.&lt;/p&gt;

&lt;p&gt;Second, the community proxy extensions I tried were too aggressive. They acted like a blunt instrument, hijacking any OpenAI-compatible request on-the-fly. When my agent tried to call DeepSeek, the extension intercepted the request and routed it to Headroom's OpenAI handler, which then forwarded my DeepSeek API key to standard OpenAI's servers. Of course, OpenAI rejected my key, and my session crashed with a wall of 401 errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bypassing the Network: The In-Process Middleware Breakthrough
&lt;/h2&gt;

&lt;p&gt;I realized that routing all actual network traffic through an intermediate proxy was too fragile for a multi-provider setup with complex authentication. I needed to separate the network layer from the compression layer.&lt;/p&gt;

&lt;p&gt;That's when I audited Headroom's source code and found a hidden gem: the stateless &lt;code&gt;/v1/compress&lt;/code&gt; API. &lt;/p&gt;

&lt;p&gt;This endpoint doesn't forward requests or touch API keys. You simply send it a raw JSON array of messages, Headroom compresses them in memory, and returns the optimized array instantly.&lt;/p&gt;

&lt;p&gt;So, I wrote a custom TypeScript middleware using my agent's native &lt;code&gt;context&lt;/code&gt; hook. Instead of hijacking sockets, the extension intercepts the prompt array in RAM right before sending it, makes a quick local POST request to Headroom's compression endpoint, merges the optimized text back, and lets my agent handle its own secure, direct connections to DeepSeek or Copilot.&lt;/p&gt;

&lt;p&gt;Here is the exact TypeScript extension I designed and deployed:&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="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ExtensionAPI&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;@earendil-works/pi-coding-agent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;readFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writeFile&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;node:fs/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;homedir&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;node:os&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;join&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;node:path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;HeadroomStats&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;totalRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;totalTokensBefore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;totalTokensAfter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;totalTokensSaved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&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;statsFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;homedir&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.pi/agent/headroom_savings.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadStats&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HeadroomStats&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&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;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statsFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&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="na"&gt;totalRequests&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="na"&gt;totalTokensBefore&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="na"&gt;totalTokensAfter&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="na"&gt;totalTokensSaved&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeadroomStats&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statsFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[Headroom Middleware] Failed to write headroom_savings.json:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExtensionAPI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;context&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;proxyUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://127.0.0.1:8787&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Is the Headroom container online?&lt;/span&gt;
    &lt;span class="k"&gt;try&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;readyCheck&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;proxyUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/readyz`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AbortSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1-second timeout for graceful fallback&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;readyCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&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;}&lt;/span&gt; &lt;span class="k"&gt;catch&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="c1"&gt;// Fall back to direct uncompressed pipeline if proxy is offline&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Call Headroom's stateless API&lt;/span&gt;
    &lt;span class="k"&gt;try&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;proxyUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/v1/compress`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Guide compressor optimization rules&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&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="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&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;compressedMessages&lt;/span&gt; &lt;span class="o"&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;messages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="c1"&gt;// --- Smart Payload Fusion ---&lt;/span&gt;
          &lt;span class="c1"&gt;// We preserve Pi-specific metadata (like entryIds and timestamps)&lt;/span&gt;
          &lt;span class="c1"&gt;// and only update the 'content' field with Headroom's compressed output.&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;finalMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&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;origMsg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;compMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compressedMessages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compMsg&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;origMsg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;compMsg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&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;...&lt;/span&gt;&lt;span class="nx"&gt;origMsg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;compMsg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&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="nx"&gt;origMsg&lt;/span&gt;&lt;span class="p"&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;tokensBefore&lt;/span&gt; &lt;span class="o"&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;tokens_before&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokensAfter&lt;/span&gt; &lt;span class="o"&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;tokens_after&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokensSaved&lt;/span&gt; &lt;span class="o"&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;tokens_saved&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokensBefore&lt;/span&gt; &lt;span class="o"&gt;&amp;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalRequests&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="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensBefore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;tokensBefore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensAfter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;tokensAfter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensSaved&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;tokensSaved&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;saveStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&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;pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokensAfter&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;tokensBefore&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headroom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Headroom: -&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pct&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% tokens`&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="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;finalMessages&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[Headroom Middleware] Compression error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&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="c1"&gt;// A native chat command to check my stats in Discord&lt;/span&gt;
  &lt;span class="nx"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headroom&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="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Displays real-time cumulative token savings from Headroom compression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalRequests&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Headroom Report: No compression events recorded yet. Send a long prompt to see savings!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&lt;/span&gt;&lt;span class="dl"&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;}&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalPct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensAfter&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensBefore&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&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;usdSaved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensSaved&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;3.00&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cumulative Savings Report — Headroom Middleware&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;──────────────────────────────────&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;`• Optimized requests: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalRequests&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;`• Total original tokens: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensBefore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;`• Compressed tokens sent: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensAfter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;`• Net token savings: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalTokensSaved&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt; tokens`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;`• Average compression efficiency: -&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;totalPct&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% tokens`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;`• Estimated cost savings: $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;usdSaved&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; USD`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;──────────────────────────────────&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data and costs flow clean, boss!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;report&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By switching to this in-process model, my keys are never sent to intermediate proxies, and my agent communicates using 100% native, verified HTTPS connections.&lt;/p&gt;




&lt;h2&gt;
  
  
  Aligning the Sockets: Inverting the Network Namespace
&lt;/h2&gt;

&lt;p&gt;To completely resolve the container startup race condition, I inverted the networking parent service in my &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead of my application starting first and creating the loopback network, I set &lt;strong&gt;Headroom as the parent service&lt;/strong&gt;. It boots up first, sets up the network namespace, binds port 8787, and performs its health check. My agent starts second and simply joins Headroom's pre-stabilized network interface (&lt;code&gt;network_mode: "service:headroom"&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;headroom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/chopratejas/headroom:code-slim&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;headroom-proxy&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:8787:8787"&lt;/span&gt; &lt;span class="c1"&gt;# Secure localhost mapping&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;agent-net&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/opt/agent/state/headroom:/home/nonroot/.headroom&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;HEADROOM_HOST=0.0.0.0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;HEADROOM_PORT=8787&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PYTHONUNBUFFERED=1&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python3"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;import&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;urllib.request;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;urllib.request.urlopen('http://127.0.0.1:8787/readyz',&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;timeout=2)"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2s&lt;/span&gt;

  &lt;span class="na"&gt;agent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;custom-agent:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-bot&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;network_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service:headroom"&lt;/span&gt; &lt;span class="c1"&gt;# Attaches to headroom's loopback namespace&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;headroom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt; &lt;span class="c1"&gt;# Wait until port 8787 is fully open and listening&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple change guarantees that port 8787 is open and listening from the first millisecond my agent boots, eliminating loopback failures completely.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real-World Results
&lt;/h2&gt;

&lt;p&gt;Since deploying this hybrid middleware architecture, my agent has run flawlessly. It has processed complex file edits, long terminal listings, and multi-turn refactoring loops with absolute stability.&lt;/p&gt;

&lt;p&gt;Here are the real statistics from my local persistent log file after a recent debugging session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Cumulative Savings Report — Headroom Middleware
──────────────────────────────────
• Optimized requests: 37
• Total original tokens: 1,280,450
• Compressed tokens sent: 140,849
• Net token savings: 1,139,601 tokens
• Average compression efficiency: -89% tokens
• Estimated cost savings: $3.4188 USD
──────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During complex operations, Headroom's SmartCrusher compressed massive tool outputs and git files by up to 92%, letting my agent stay well within deep context windows and reducing response latency significantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Enterprise Blueprint: Scaling to Enterprise with Kong, OIDC &amp;amp; Entra ID
&lt;/h2&gt;

&lt;p&gt;This local setup serves as a solid proof of concept. The next phase is scaling this context-compression architecture across our corporate GCP environment to support hundreds of developers. &lt;/p&gt;

&lt;p&gt;To achieve this securely and at scale, the architecture will transition into a centralized, highly available cloud-native service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Kubernetes Orchestration (GKE):&lt;/strong&gt; Centralize Headroom proxy pods inside standard private Google Kubernetes Engine (GKE) clusters. These pods scale horizontally via standard HPAs and share a distributed cache database utilizing GCP Memorystore (Redis) to synchronize Context-Compressed Retrieval (CCR) hashes across stateless replicas.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;API Gateway &amp;amp; Security (Kong with OIDC):&lt;/strong&gt; To comply with strict data privacy guidelines, the centralized GKE service will be placed behind Kong API Gateway, integrated with OIDC (OpenID Connect) and Entra ID (formerly Azure Active Directory). &lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Bring-Your-Own-Key (BYOK) Identity Propagation:&lt;/strong&gt; Kong will validate the developer’s enterprise JWT, propagate their unique developer identity, and allow Headroom to compress prompts on-the-fly while forwarding the individual developer's OAuth credentials securely to upstream providers—ensuring flawless auditability, security compliance, and dynamic access quota controls.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  But for this implementation, I will write other article, so if you are interested, you just have to follow me ;)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What's in Your Tech Stack?
&lt;/h2&gt;

&lt;p&gt;Taming context windows is one of the most critical challenges as we move towards highly autonomous agentic workflows. &lt;/p&gt;

&lt;p&gt;I'd love to know: what tools or strategies are you using to manage your context size and keep your LLM bills under control? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>The Hidden Architecture of the Agentic Enterprise: Model Stack, Tokenomics, and Harness</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Tue, 30 Jun 2026 10:25:28 +0000</pubDate>
      <link>https://dev.to/sarony11/the-hidden-architecture-of-the-agentic-enterprise-model-stack-tokenomics-and-harness-384k</link>
      <guid>https://dev.to/sarony11/the-hidden-architecture-of-the-agentic-enterprise-model-stack-tokenomics-and-harness-384k</guid>
      <description>&lt;p&gt;Every day there are new buzzwords, new advances in AI, new repositories with thousands of stars on GitHub, new solutions, new models, new products... everything moves so fast, it's not you. But if you're in charge, you're the one who has to make decisions and create the strategy.&lt;/p&gt;

&lt;p&gt;CTOs and VPs of Engineering are experiencing severe AI whiplash. Every week, a new model drops, promising to make the previous week’s stack obsolete. In a desperate bid to show "AI adoption" to board members and investors, companies are rush-installing turnkey developer tools: GitHub Copilot, Claude Code, and flashy new enterprise coding platforms.&lt;/p&gt;

&lt;p&gt;On paper, the productivity graph goes up. In reality, these organizations are committing strategic suicide. They are building the core engine of their future business on rented land, blind to the architectural and economic realities of the AI era.&lt;/p&gt;

&lt;p&gt;To scale engineering in this new paradigm, leaders must transition from &lt;strong&gt;"Vibe (Babysitting) Coding"&lt;/strong&gt;—unstructured prompting of monolithic models—to &lt;strong&gt;Agentic (Autonomous) Engineering&lt;/strong&gt;: the deliberate design of autonomous, product multi-agent factory systems.&lt;/p&gt;

&lt;p&gt;Here is the deep though and strategic blueprint for leading a resilient, cost-effective, and independent Agentic Enterprise.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Turnkey Trap and the Reality of the "Cognitive Rugpull"
&lt;/h2&gt;

&lt;p&gt;The allure of out-of-the-box corporate AI tools is simple: install a plugin, pay a flat subscription, and let your developers get to work. But this convenience masks a catastrophic risk: &lt;strong&gt;Vendor Lock-in at the cognitive (hardness) level.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you delegate your agentic logic—how context is gathered, how tools are invoked, and how prompts are structured—to a third-party black box, you yield sovereignty over your Software Development Life Cycle (SDLC).&lt;/p&gt;

&lt;p&gt;We have already seen this play out in real-time. Consider the frequent updates to commercial coding assistants like &lt;strong&gt;Antigravity&lt;/strong&gt;. Since its release, the platform has repeatedly modified its internal system rules and underlying model weights without warning. The result? Entire development workflows were bricked overnight. Teams that relied on Antigravity’s specific behavior woke up to find their agents incapable of completing tasks they had successfully executed the day before.&lt;/p&gt;

&lt;p&gt;When a vendor decides to alter their pricing, restrict API access, or change their safety guardrails, your engineering pipeline collapses. If your proprietary business logic and development workflows are trapped inside their closed system, you are helpless.&lt;/p&gt;

&lt;p&gt;I have a clear conclusion here, you must own your agentic architecture. If you don't build your own control layer, you are not innovating; you are just outsourcing your core intellectual property to a vendor who can change the rules of your business at any moment.&lt;/p&gt;

&lt;p&gt;And once you own that control layer, the next problem is resilience: you need a model stack that can absorb vendor shifts without breaking your workflows or your economics. That is why the architecture has to move from dependency on one provider to a diversified, swappable model stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Resilient Model Stack: Surviving the Commodity War
&lt;/h2&gt;

&lt;p&gt;Relying on a single AI provider (like Anthropic’s Claude or OpenAI's GPT) is a massive strategic and operational point of failure. Modern agentic engineering is not about picking the "best" model; it is about building a system flexible enough to &lt;strong&gt;hot-swap&lt;/strong&gt; models based on cost, latency, speed, and availability.&lt;/p&gt;

&lt;p&gt;Marrying your company to a single vendor is a critical business risk. Providers can go down, they can change model behavior, they can alter weights or policies, and they can even be constrained or censored, as we have recently seen with models like Claude Fable. If your entire engineering workflow depends on one external provider, you are not just adopting a tool; you are accepting a single point of failure for your company’s operating system.&lt;/p&gt;

&lt;p&gt;For that reason, using multiple providers and even open models is not a nice-to-have. It is a strategic requirement. A resilient platform should be able to route work across closed and open ecosystems, preserving continuity when a provider changes direction, degrades quality, raises prices, or becomes inaccessible.&lt;/p&gt;

&lt;p&gt;The solution is to construct a resilient &lt;strong&gt;Model Stack&lt;/strong&gt; divided into three distinct levels of capacity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  ▲
                 / \
                /   \     SOTA (Frontier Models)
               / SOTA\    - Claude 3.5 Opus, GPT-5.5
              /-------\   - Reasoning, planning, architecture
             /         \
            / WORKHORSE \  Workhorses (Value &amp;amp; Scale)
           /             \ - GLM 5.2, Gemini Pro
          /---------------\- 90% SOTA capability, 5x cheaper
         /                 \
        /    LIGHTWEIGHT    \ Lightweight &amp;amp; Local (Speed &amp;amp; Privacy)
       /                     \- Qwen, Gemma, Llama 8B
      /_______________________\- Formatting, micro-tasks, local execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Tier 1: SOTA (State-of-the-Art):&lt;/strong&gt; These are frontier models (e.g., Claude Fable, Claude Opus, GPT-5.5). These are your lead architects, reserved strictly for the most complex reasoning, deep planning, and foundational codebase restructuring.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tier 2: Workhorses (The Value Layer):&lt;/strong&gt; Highly capable models (such as GLM 5.2 or Gemini 3.5 Flash or Gemini 3.1 Pro) that deliver &lt;strong&gt;90% of a SOTA model's capability at a 5x lower cost&lt;/strong&gt;. This is where the bulk of your system's operational work should live.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tier 3: Lightweight / Local:&lt;/strong&gt; Fast, economical, and often local models (like Qwen, Gemma, Llama 8B) for simple tasks, structured data formatting, input parsing, or processes requiring absolute data privacy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;True agentic engineering isn't about marrying one AI; it's about building a routing system flexible enough to hot-swap them based on availability, latency, and required performance. If a lab update degrades a SOTA model or alters its performance, your system’s routing logic should immediately reroute the workload to another tier-equivalent model without your engineering team ever feeling the friction.&lt;/p&gt;

&lt;p&gt;That routing flexibility is not just an architectural preference; it is the first lever of your cost structure. Once the model stack is diversified, the next question is no longer which model to use, but how much each interaction is actually costing you.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Tokenomics: Decoding the "Communication Tax"
&lt;/h2&gt;

&lt;p&gt;Traditional cloud architecture measures success in server compute and database read/write cycles. In the agentic era, we must master &lt;strong&gt;Tokenomics&lt;/strong&gt;: the study of operational efficiency, resource allocation, and cognitive cost in multi-agent systems.&lt;/p&gt;

&lt;p&gt;We are used to looking at AI costs as a flat rate per million tokens. But in multi-agent systems, cost behavior becomes highly asymmetrical. Consider these two counter-intuitive realities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Code Review Bottle-neck:&lt;/strong&gt; Recent industry studies show that in an agentic SDLC, the &lt;strong&gt;Code Review stage can consume up to 59.4% of total token expenditures&lt;/strong&gt;. Why? Because review is inherently iterative. Agents must constantly pass large code files back and forth, analyzing diffs, proposing changes, and re-evaluating code until it passes compliance.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Communication Tax:&lt;/strong&gt; In multi-agent systems, input tokens (the context sent &lt;em&gt;to&lt;/em&gt; the model) dwarf output tokens (the code generated). This is the "Communication Tax." Every time an agent explains a task to another agent, or passes state metadata, you are burning money on input tokens.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Agent A] ---&amp;gt; (State + Code + Context) ---&amp;gt; [Agent B]
               └─────────┬─────────┘
                 INPUT TOKENS = The "Communication Tax"
                 (Accumulates exponentially in loops)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal of Tokenomics is not to spend less. &lt;strong&gt;The goal is Token Arbitrage&lt;/strong&gt;: designing your system so that the economic value of the agent's output dramatically exceeds the transactional cost of the tokens consumed to generate it. &lt;/p&gt;

&lt;p&gt;If an agent burns $5.00 worth of tokens to successfully write a secure, compliant microservice that would have taken a human engineer four hours to build, you have achieved massive arbitrage. It's about generating more business value per token than the cost of execution.&lt;/p&gt;

&lt;p&gt;But token arbitrage does not happen by accident. To make these economics repeatable, you need a control layer that shapes how much context an agent sees, how many steps it takes, and when it is allowed to spend tokens. That control layer is the harness.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Harness Engineering: Forcing Determinism onto Chaos
&lt;/h2&gt;

&lt;p&gt;Large Language Models are probabilistic engines—they operate on probability, not logic. How do you build a predictable, enterprise-grade product on top of an unpredictable engine?&lt;/p&gt;

&lt;p&gt;To improve your tokenomics and guarantee an agent's behavior, the most efficient approach is &lt;strong&gt;Harness Engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The "Harness" is the custom domain rules, infrastructure, tooling, and environment that wraps around the AI model. It manages memory storage, handles token budgets, controls tool execution, and strictly governs what the agent can see and do, and how to do it. It is how you codify all your domain, product, and business logic into the system, making the final result deterministic.&lt;/p&gt;

&lt;p&gt;To optimize your corporate harness and control both cost and quality, your platform must enforce four strategic pillars:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Dynamic Routing Logic:&lt;/strong&gt; The harness must prevent "cognitive overkill." It must intercept requests and route them to the most economical model capable of solving them successfully. Never throw a SOTA model at a formatting problem.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Deterministic Micro-stepping:&lt;/strong&gt; Agents hallucinate and wander when overwhelmed with large, ambiguous goals. The harness must break massive instructions down into tiny, verifiable, sequential micro-steps. For example, forcing an agent to write and execute a unit test &lt;em&gt;before&lt;/em&gt; it is allowed to modify the source code.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Domain &amp;amp; Directory Isolation (Context Control):&lt;/strong&gt; Giving an agent access to your entire codebase is a security nightmare and an economic disaster (due to context-window bloat). The harness must strictly limit the agent's viewport. A frontend UI agent has no business reading backend database migrations or Docker configurations—saving thousands of tokens on every run.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Engineering Harness Tooling:&lt;/strong&gt; Work on the infrastructure surrounding the agent (skills, specialized prompts, custom tools). Provide your agents with highly specialized, custom internal tools (retrieval systems, APIs, syntax checkers). By giving the model precise tools rather than asking it to "hallucinate" solutions, you force its output to be highly deterministic, repeatable, and optimal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain Context - Security, Compliance and Operational Rules:&lt;/strong&gt; A strong harness does not just route work and enforce steps. It also injects the specific context of the domain: security boundaries, compliance requirements, approved methodologies, naming conventions, escalation paths, and the exact way a team expects work to be executed. That context changes everything, because the same agent will behave very differently depending on whether it is operating inside a fintech, a healthcare platform, an internal developer tool, or a product team with its own delivery standards.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  In practice, this means the harness should encode the rules that belong to the task, the system, the domain, and the company itself. Without that layer, an agent may still be fast, but it will be fast in the wrong direction.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  5. The Dual-Agent Ecosystem: AI Product Factories vs. The Engineering Vanguard
&lt;/h2&gt;

&lt;p&gt;To implement this without overwhelming your engineering teams, your platform should divide agent labor into a clean, two-tiered ecosystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                      ┌─────────────────────────────────┐
                      │    Agentic Platform Core        │
                      └────────────────┬────────────────┘
                                       │
                ┌──────────────────────┴──────────────────────┐
                ▼                                             ▼
  ┌───────────────────────────┐                 ┌───────────────────────────┐
  │    AI Product Factory     │                 │   The Engineering Vanguard│
  ├───────────────────────────┤                 ├───────────────────────────┤
  │ - Product Agents          │                 │ - High-Level Eng Agents   │
  │ - Predictable, high-vol   │                 │ - Extreme Custom Harness  │
  │ - Value/Lightweight Stack │                 │ - SOTA Frontier Models    │
  │ - Boilerplate, CRUD, UI   │                 │ - Architecture &amp;amp; Design   │
  └───────────────────────────┘                 └───────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The AI Product Factory (Product Agents)
&lt;/h3&gt;

&lt;p&gt;The vast majority of software development in an enterprise is predictable, repetitive volume work: generating standard CRUD endpoints, writing basic unit tests, updating UI components, or building simple API integrations.&lt;/p&gt;

&lt;p&gt;Your platform must package these tasks into &lt;strong&gt;Product Agents&lt;/strong&gt;. These are highly constrained, specialized agents designed to act as an "AI Product Factory." They run on the cheapest possible Workhorse and Lightweight models, executing predictable code paths. &lt;/p&gt;

&lt;p&gt;Internal product teams, junior devs, and even product managers can trigger these agents to handle the heavy lifting, maintaining high throughput at an incredibly low token cost. They handle the predictable bulk of a company's product work.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Engineering Vanguard (Engineering Agents)
&lt;/h3&gt;

&lt;p&gt;At the other end of the spectrum is the frontier of your business. Your Staff, Principal, and Senior engineers should never be writing boilerplate. They are paid to make high-stakes architectural decisions, design complex systems, and solve structural bottlenecks.&lt;/p&gt;

&lt;p&gt;For this elite tier, your platform provides &lt;strong&gt;Engineering Agents&lt;/strong&gt;. These are high-level agents operating within deeply customized and personalized harnesses. Running on the absolute edge of frontier (SOTA) intelligence, they are equipped with deep system access and specialized developer skills. &lt;/p&gt;

&lt;p&gt;They act as autonomous co-architects, assisting senior talent in executing sweeping, transformative refactors and ensuring your core architecture remains world-class.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping up and last words
&lt;/h2&gt;

&lt;p&gt;The rapid evolution of AI models is a distraction. If your strategy is to wait for the next model release to solve your engineering bottlenecks, you have already lost. Models are becoming cheap commodities.&lt;/p&gt;

&lt;p&gt;The companies that dominate the next years will not be those who bought the best turnkey AI subscriptions. It will be those who built their own &lt;strong&gt;Agentic Engineering Platforms&lt;/strong&gt; and spend human resources in building their &lt;strong&gt;Agentic Engineering Experts&lt;/strong&gt; that research, investigate and lead the IA way, filtering out the noise and capitalize on the true value.&lt;/p&gt;

&lt;p&gt;By owning your corporate harness, implementing a resilient model stack, and separating your AI labor into Product Factories and Vanguard Engineers, you insulate your company from vendor lock-in, control your tokenomics, and build an unshakeable foundation.&lt;/p&gt;

&lt;p&gt;Stop vibe coding. Stop renting your cognitive infrastructure. Build the platform that builds your product.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>automation</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Agentic Platform Engineering: How to Build an Agent Infrastructure That Scales From Your Laptop to the Enterprise</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Thu, 19 Mar 2026 00:51:33 +0000</pubDate>
      <link>https://dev.to/sarony11/agentic-platform-engineering-how-to-build-an-agent-infrastructure-that-scales-from-your-laptop-to-11np</link>
      <guid>https://dev.to/sarony11/agentic-platform-engineering-how-to-build-an-agent-infrastructure-that-scales-from-your-laptop-to-11np</guid>
      <description>&lt;p&gt;&lt;em&gt;Starting local is not thinking small. It's thinking strategically.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Stripe recently published a series on how they build "Minions" — fully autonomous coding agents that take a task and complete it end-to-end without human intervention. One agent reads the codebase, another writes the implementation, another runs the tests, another reviews the result. All in parallel. All coordinated. All producing production-ready code at scale.&lt;/p&gt;

&lt;p&gt;Reading that, most engineers react one of two ways. Either "that's years away for us" — or they start thinking about what foundations would need to be in place to even begin moving in that direction.&lt;/p&gt;

&lt;p&gt;This article is about the second reaction.&lt;/p&gt;

&lt;p&gt;What Stripe describes is not a product you buy. It's a capability you build, incrementally, on top of solid infrastructure. And that infrastructure — the way agent configuration is stored, versioned, distributed, and composed — is what separates teams that can scale AI seriously from teams that are still copy-pasting prompts into chat windows.&lt;/p&gt;

&lt;p&gt;I call this discipline &lt;strong&gt;Agentic Platform Engineering&lt;/strong&gt;. And its first principle is simple: &lt;strong&gt;treat agent intelligence as infrastructure, not as improvisation.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem at Any Scale
&lt;/h2&gt;

&lt;p&gt;Whether you're a solo engineer with 10 repositories or a platform team with 200, you hit the same structural problem when you try to work seriously with AI agents.&lt;/p&gt;

&lt;p&gt;At the individual level, it looks like this: you spend time configuring your agent well — crafting instructions, building reusable procedures, defining what it should and shouldn't do depending on where you're working. Then you switch machines, reinstall a tool, or try a different agent. Your configuration is gone. You start over.&lt;/p&gt;

&lt;p&gt;At the team level, it's worse: every engineer has their own private, undocumented, non-transferable agent setup. There's no shared knowledge about how agents should behave in your codebase, no consistency in what they can and cannot do, no way to onboard a new member into an agentic workflow. The AI capability of your team cannot scale because it lives in individual heads and local files.&lt;/p&gt;

&lt;p&gt;And at the enterprise level — the level where Stripe operates — you cannot even begin to think about autonomous agents running pipelines if you haven't solved the fundamental question: &lt;strong&gt;where does agent configuration live, who owns it, and how does it reach every context where it's needed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most engineers interact with AI agents in one of two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ad-hoc&lt;/strong&gt;: No configuration, just prompting. Works for one-off tasks, but the agent has no memory of your stack, your conventions, or your constraints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single-file config&lt;/strong&gt;: One big &lt;code&gt;AGENTS.md&lt;/code&gt; or &lt;code&gt;CLAUDE.md&lt;/code&gt; at the root of a repo. Better, but it doesn't scale — the same instructions get injected everywhere, regardless of whether they're relevant, and they live in one repo while you work across twenty.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither approach is infrastructure. Neither can scale. Neither gives you what you'd need to move toward autonomous multi-agent systems.&lt;/p&gt;

&lt;p&gt;The question is: what would infrastructure actually look like?&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture: Three Repos, One System
&lt;/h2&gt;

&lt;p&gt;The solution I landed on separates concerns into three distinct repositories, each with a single, well-defined responsibility. This is not a personal productivity hack. It's a deliberate architectural pattern that mirrors how platform engineering works for any shared infrastructure — you version it, you document what exists, and you decouple the interface from the implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent-library/    ← The brain (tool-agnostic intelligence)
agent-setup/      ← The bridge (tool-specific deployment)
resource-catalog/ ← The map (inventory of everything)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain each one.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. &lt;code&gt;agent-library&lt;/code&gt; — The Brain
&lt;/h3&gt;

&lt;p&gt;This is the &lt;strong&gt;single source of truth for everything the agent knows and how it behaves&lt;/strong&gt;. It contains no tool-specific configuration. If tomorrow I switch from one AI coding tool to another, this repo stays untouched.&lt;/p&gt;

&lt;p&gt;The structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent-library/
├── library.yaml          ← Central manifest
├── SKILLS-INDEX.md       ← Human-readable index of all skills
├── layers/               ← Context-specific instructions
│   ├── global.md         ← Identity, principles, environment map
│   ├── repos.md          ← Shared git conventions
│   ├── work/             ← Work domain
│   │   ├── domain.md     ← Conservative rules, safety constraints
│   │   ├── terraform.md  ← Terraform-specific workflow
│   │   ├── gitops.md     ← GitOps/FluxCD rules
│   │   └── code.md       ← Code conventions
│   └── personal/         ← Personal domain
│       ├── domain.md     ← Experimental mode, fast iteration
│       ├── fintech-app.md
│       └── infra-gcp.md
├── skills/               ← Reusable procedures
│   ├── global/           ← Available everywhere
│   └── work/             ← Domain-specific
├── rules/                ← Always-on constraints
└── prompts/              ← Reusable prompt templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key concept is &lt;strong&gt;layers&lt;/strong&gt;. Each layer is a Markdown file that becomes an &lt;code&gt;AGENTS.md&lt;/code&gt; (or equivalent) for a specific directory. They are designed to be &lt;strong&gt;cumulative&lt;/strong&gt; — the agent loads them from parent to child, each adding context on top of the previous one.&lt;/p&gt;

&lt;p&gt;When the agent is working in &lt;code&gt;~/repos/work/terraform/&lt;/code&gt;, it loads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.agent/AGENTS.md              → global.md        (who I am, core principles)
~/repos/AGENTS.md               → repos.md         (git conventions)
~/repos/work/AGENTS.md          → work/domain.md   (conservative, safety-first)
~/repos/work/terraform/AGENTS.md → work/terraform.md (terraform workflow)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer is laser-focused. &lt;code&gt;global.md&lt;/code&gt; doesn't know about Terraform. &lt;code&gt;work/terraform.md&lt;/code&gt; doesn't know about React. The agent assembles its context from the bottom up, with exactly the information it needs for where it currently is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;library.yaml&lt;/code&gt; manifest&lt;/strong&gt; is the glue. It declares every layer, skill, rule, and prompt — what it is, where it lives in the repo, and where it should be deployed on the filesystem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;layers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;work-terraform&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terraform-specific&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rules&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;work&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;domain"&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;layers/work/terraform.md&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/repos/work/terraform/AGENTS.md&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~/repos/work/terraform/*"&lt;/span&gt;

&lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform-plan&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terraform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;plan/apply&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;workflow"&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;skills/work/terraform-plan.md&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~/repos/work/terraform/*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. &lt;code&gt;agent-setup&lt;/code&gt; — The Bridge
&lt;/h3&gt;

&lt;p&gt;This repo is &lt;strong&gt;the adapter between the tool-agnostic brain and the specific AI agent tool&lt;/strong&gt; I use today. If I switch tools next year, I replace only this repo. The brain stays the same.&lt;/p&gt;

&lt;p&gt;Its core is a single &lt;code&gt;setup.sh&lt;/code&gt; script that reads &lt;code&gt;library.yaml&lt;/code&gt; and deploys everything via symlinks:&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;# Creates: ~/repos/work/terraform/AGENTS.md → agent-library/layers/work/terraform.md&lt;/span&gt;
&lt;span class="c"&gt;# Creates: ~/.agent/skills/terraform-plan → agent-library/skills/work/terraform-plan.md&lt;/span&gt;
&lt;span class="c"&gt;# ... and so on for every layer, skill, rule, and prompt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why symlinks instead of copies?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because when I edit a layer in &lt;code&gt;agent-library&lt;/code&gt;, the change is immediately live everywhere. No re-deployment needed. &lt;code&gt;setup.sh&lt;/code&gt; only needs to run again when I add a &lt;em&gt;new&lt;/em&gt; file (a new symlink to create). For edits to existing files, the symlink already points to the right place.&lt;/p&gt;

&lt;p&gt;The repo also contains tool-specific settings, keybindings, and extensions — things that only make sense for a specific tool.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;code&gt;resource-catalog&lt;/code&gt; — The Map
&lt;/h3&gt;

&lt;p&gt;This is the &lt;strong&gt;index of everything that exists&lt;/strong&gt; in my engineering ecosystem. It follows the &lt;a href="https://backstage.io" rel="noopener noreferrer"&gt;Backstage&lt;/a&gt; catalog format — the same standard used in enterprise engineering platforms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# components/agent-library.yaml&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backstage.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Component&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-library&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tool-agnostic&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;configuration&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;library"&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;github.com/project-slug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-username/agent-library&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ai-agent-config&lt;/span&gt;
  &lt;span class="na"&gt;lifecycle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-name&lt;/span&gt;
  &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;personal-ai-agent-platform&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every repository I own — infrastructure, applications, documentation, and yes, the agent-library itself — is registered here with its type, owner, system, and source location.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The catalog is not where agent logic lives.&lt;/strong&gt; It's a map, not an engine. The distinction matters: the catalog tells you &lt;em&gt;that&lt;/em&gt; &lt;code&gt;agent-library&lt;/code&gt; exists and what it is. The &lt;code&gt;agent-library&lt;/code&gt; itself contains &lt;em&gt;what&lt;/em&gt; the agent knows. Mixing these two concerns would be like embedding source code inside your &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Skills: The Reusable Procedure Library
&lt;/h2&gt;

&lt;p&gt;Beyond layers (which define &lt;em&gt;how the agent behaves&lt;/em&gt;), the library contains &lt;strong&gt;skills&lt;/strong&gt; — reusable, step-by-step procedures for common tasks.&lt;/p&gt;

&lt;p&gt;A skill looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Skill: Terraform Plan&lt;/span&gt;

Use this skill when working with Terraform in the work domain.

&lt;span class="gu"&gt;## Steps&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Check context — confirm directory and workspace
&lt;span class="p"&gt;2.&lt;/span&gt; terraform fmt -recursive
&lt;span class="p"&gt;3.&lt;/span&gt; terraform validate
&lt;span class="p"&gt;4.&lt;/span&gt; terraform plan -out=tfplan
&lt;span class="p"&gt;5.&lt;/span&gt; Review plan — summarize what will change
&lt;span class="p"&gt;6.&lt;/span&gt; Highlight risks — flag any destroys or critical changes
&lt;span class="p"&gt;7.&lt;/span&gt; Wait for confirmation — never apply without explicit approval
...

&lt;span class="gu"&gt;## Red Flags (Stop and Ask)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Any resource marked for destruction
&lt;span class="p"&gt;-&lt;/span&gt; Changes to IAM policies
&lt;span class="p"&gt;-&lt;/span&gt; Changes to production databases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skills are invoked explicitly: &lt;code&gt;/skill:terraform-plan&lt;/code&gt;. They're never loaded automatically — that's intentional. The agent doesn't pre-load every procedure it might need. It loads the skill when the task calls for it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Token Efficiency Design
&lt;/h2&gt;

&lt;p&gt;This is where the architecture earns its keep.&lt;/p&gt;

&lt;p&gt;A naive approach would be: put everything in one big &lt;code&gt;AGENTS.md&lt;/code&gt;. All the rules, all the skills, all the context. The agent always knows everything.&lt;/p&gt;

&lt;p&gt;The problem: that file becomes enormous. Every single message you send to the agent carries the full weight of that context as tokens. You're paying for Terraform rules when you're writing a Python script. You're loading GitOps procedures when you're working on documentation.&lt;/p&gt;

&lt;p&gt;The architecture solves this at three levels:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 1: Layers are scoped by directory.&lt;/strong&gt; The Terraform layer only activates when you're in &lt;code&gt;~/repos/work/terraform/&lt;/code&gt;. Not in your React app. Not in your docs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 2: Each layer only declares what's relevant at its level.&lt;/strong&gt; &lt;code&gt;global.md&lt;/code&gt; lists 6 universal skills (debug, code-review, refactor, test, documentation, git-workflow). It does &lt;em&gt;not&lt;/em&gt; list &lt;code&gt;terraform-plan&lt;/code&gt; or &lt;code&gt;catalog-management&lt;/code&gt; — those are irrelevant in most contexts. &lt;code&gt;work/terraform.md&lt;/code&gt; lists &lt;code&gt;terraform-plan&lt;/code&gt; and nothing else, because that's the only skill you need there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 3: Meta-skills are scoped to their home.&lt;/strong&gt; &lt;code&gt;create-skill&lt;/code&gt; (the skill that creates new skills) is only available inside &lt;code&gt;agent-library/&lt;/code&gt;. &lt;code&gt;catalog-management&lt;/code&gt; is only available inside &lt;code&gt;resource-catalog/&lt;/code&gt;. Why would the agent know how to modify the agent library while it's working on your fintech app?&lt;/p&gt;

&lt;p&gt;The result: when the agent is in &lt;code&gt;work/terraform/&lt;/code&gt;, its active context is exactly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;6 global skills&lt;/li&gt;
&lt;li&gt;1 domain skill (infrastructure-review)&lt;/li&gt;
&lt;li&gt;1 directory skill (terraform-plan)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. No noise.&lt;/p&gt;




&lt;h2&gt;
  
  
  Disaster Recovery in Under 5 Minutes
&lt;/h2&gt;

&lt;p&gt;The entire system is built for one guarantee: &lt;strong&gt;if everything breaks, you can rebuild from scratch in under 5 minutes.&lt;/strong&gt;&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;# Step 1: Clone the three repos&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/repos &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ~/repos
git clone git@github.com:your-username/agent-library.git
git clone git@github.com:your-username/agent-setup.git
git clone git@github.com:your-username/resource-catalog.git

&lt;span class="c"&gt;# Step 2: Deploy&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;agent-setup &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; bash setup.sh

&lt;span class="c"&gt;# Step 3: Verify&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/repos/work/terraform &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; your-agent &lt;span class="s2"&gt;"What context am I in?"&lt;/span&gt;
&lt;span class="c"&gt;# → Agent responds with terraform-specific context ✓&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done. The agent has its full identity, all its domain knowledge, all its skills, and all the right rules for every directory it works in.&lt;/p&gt;

&lt;p&gt;This is only possible because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Everything is in git.&lt;/strong&gt; No local-only configuration that can be lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The brain is separate from the tool.&lt;/strong&gt; Reinstalling the tool doesn't lose the intelligence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The manifest declares everything.&lt;/strong&gt; &lt;code&gt;library.yaml&lt;/code&gt; is the complete description of the system — &lt;code&gt;setup.sh&lt;/code&gt; just executes it.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Mental Model: A Package Manager for Agent Intelligence
&lt;/h2&gt;

&lt;p&gt;Think of it like a software package manager, but for how agents think and behave.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;library.yaml&lt;/code&gt; is your &lt;code&gt;package.json&lt;/code&gt; — it declares everything that should exist and what it does. &lt;code&gt;setup.sh&lt;/code&gt; is your &lt;code&gt;npm install&lt;/code&gt; — it takes the manifest and wires everything up on any machine. The layers are your source modules — composable, scoped, loaded on demand. The skills are your function library — procedures you invoke when you need them, not before.&lt;/p&gt;

&lt;p&gt;The difference from a traditional package manager: the "packages" here are not code. They're &lt;em&gt;instructions for how to reason&lt;/em&gt; in a given context.&lt;/p&gt;

&lt;p&gt;This matters beyond the individual level. If you're a platform team and you want every engineer to work with agents consistently — the same safety rules around production, the same conventions for code review, the same escalation procedures — you publish to &lt;code&gt;agent-library&lt;/code&gt;. Engineers run &lt;code&gt;setup.sh&lt;/code&gt;. Done. The intelligence is distributed, versioned, and auditable. Just like any other shared infrastructure.&lt;/p&gt;

&lt;p&gt;This is the foundation Stripe's approach requires. Before you can run autonomous agents in parallel on real codebases, you need to have solved: where do agents get their instructions? Who updates them? How do changes propagate? How do you ensure an agent working on your payment service doesn't behave like an agent working on an internal tool?&lt;/p&gt;

&lt;p&gt;The architecture described in this article is an answer to those questions — starting from a single developer setup, but designed to scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Looks Like Day-to-Day
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When I open a terminal in &lt;code&gt;~/repos/work/terraform/&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
The agent already knows it's in conservative mode, that any &lt;code&gt;terraform apply&lt;/code&gt; needs a reviewed plan and explicit confirmation, that pre-commit hooks must run before any commit, and exactly which skill to use for the full workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When I open a terminal in &lt;code&gt;~/repos/personal/fintech-app/&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
The agent knows it can move fast, that this is a Python financial analysis platform, that API keys live in environment variables and never in code, and that tests run before committing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When I want to add a new skill:&lt;/strong&gt;&lt;br&gt;
I run &lt;code&gt;/skill:create-skill&lt;/code&gt;. The agent walks me through creating the file, registering it in &lt;code&gt;library.yaml&lt;/code&gt; with the right scope, updating &lt;code&gt;SKILLS-INDEX.md&lt;/code&gt;, and committing. The skill is live the moment it's committed — no redeployment needed (symlinks).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When a colleague joins my team or I get a new machine:&lt;/strong&gt;&lt;br&gt;
Three git clones and one bash script. Same agent, same behavior, same context everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Design Decisions That Matter
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why not one big repo?&lt;/strong&gt; Separation of concerns. The brain shouldn't depend on the tool. The catalog shouldn't contain executable logic. Mix them and you create coupling that makes the whole system fragile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Backstage format for the catalog?&lt;/strong&gt; It's an industry standard built exactly for this — describing what exists, who owns it, and how it relates to other things. It's human-readable, tool-agnostic, and designed to scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why symlinks instead of copies?&lt;/strong&gt; Real-time updates without redeployment. Edit &lt;code&gt;terraform.md&lt;/code&gt; in the library, it's immediately live in &lt;code&gt;~/repos/work/terraform/&lt;/code&gt;. No sync step, no drift between source and deployed config.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why scope skills to directories instead of loading all of them?&lt;/strong&gt; Token efficiency and cognitive clarity. An agent with 30 loaded skills is an agent that has to decide which one applies. An agent with 2 loaded skills knows exactly what to use.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Haven't Built Yet
&lt;/h2&gt;

&lt;p&gt;This is an honest article, so here's what's still on the roadmap — and what brings the architecture closer to the Stripe model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extensions&lt;/strong&gt; (next): Custom tools for things like catalog lookup, repo navigation, and library sync directly from the terminal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP integration&lt;/strong&gt;: Model Context Protocol servers for deeper, structured tool integrations — giving agents access to live data sources, not just static instructions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-agent orchestration&lt;/strong&gt;: The ability to spawn specialized agents in parallel for complex tasks — one reads the codebase, another implements, another validates. This is the direction Stripe's Minions move in, and this architecture is specifically designed so the layer system can feed each specialized agent exactly the context it needs, nothing more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized distribution&lt;/strong&gt;: Moving from local symlinks to a pull-based model where any machine or CI environment can fetch the latest agent configuration from &lt;code&gt;agent-library&lt;/code&gt; automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these is a step up the autonomy ladder. But none of them are possible without the foundation: versioned, scoped, composable agent configuration that you control.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Stripe's Minions are impressive. But they're not magic — they're the result of building the right infrastructure first.&lt;/p&gt;

&lt;p&gt;The architecture described here — three repos, clear separation of concerns, a manifest-driven deployment, and scoped context loading — is that infrastructure, starting at the smallest possible scale. One developer, one machine, three git repositories.&lt;/p&gt;

&lt;p&gt;The local setup is not the destination. It's the proof of concept for a pattern that scales: agent intelligence is configuration, configuration belongs in git, and git belongs in a system where it can be versioned, distributed, and composed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start local. Think at scale. Build the foundation that makes the next step possible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's Agentic Platform Engineering.&lt;/p&gt;




&lt;p&gt;UPDATE - 1&lt;br&gt;
The Cross-Org Agent Discovery Problem&lt;/p&gt;

&lt;p&gt;Since publishing this article, a great discussion sparked by &lt;a class="mentioned-user" href="https://dev.to/globalchatads"&gt;@globalchatads&lt;/a&gt; in the comments regarding a critical question: &lt;em&gt;This local Monorepo/Symlink architecture is great for a single developer, but how does it actually scale to a multi-team Enterprise environment?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If Team A (Security) has an agent that needs to run an audit tool owned by Team B (Networking), how does Team A's agent discover that tool? Naively, we could give the agent a Git Personal Access Token (PAT) to read Team B’s repository. However, in a zero-trust enterprise, sharing Git tokens across domains creates a massive security overhead and tight  coupling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: Cross Organization Discovery for Agents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of relying on shared filesystems or direct repository access, we need a network-routable &lt;strong&gt;Service Registry&lt;/strong&gt;. Taking inspiration from standard web protocols, I've integrated the &lt;strong&gt;RFC 8615 (&lt;code&gt;.well-known/&lt;/code&gt;) directory pattern&lt;/strong&gt; into this architecture.&lt;/p&gt;

&lt;p&gt;Here is how a distributed (Polyrepo) setup works in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitOps as the Source of Truth:&lt;/strong&gt; Team B maintains their local &lt;code&gt;agent-library&lt;/code&gt; in their own repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Build Step:&lt;/strong&gt; When changes are merged, a CI/CD pipeline parses their internal &lt;code&gt;library.yaml&lt;/code&gt;, extracts the tools meant for public consumption (e.g., MCP server endpoints), and compiles a standardized &lt;code&gt;agent-capabilities.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Deployment:&lt;/strong&gt; This JSON is published to an internal, highly available endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Discovery:&lt;/strong&gt; When Team A's agent needs to interact with the Networking domain, it simply queries &lt;a href="https://api.networking.internal/.well-known/agent-capabilities.json%60" rel="noopener noreferrer"&gt;https://api.networking.internal/.well-known/agent-capabilities.json`&lt;/a&gt; to understand what tools are available and what OAuth scopes are required.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To demonstrate this, I have updated the &lt;strong&gt;&lt;a href="https://github.com/Sarony11/agentic-infrastructure-bootstrap" rel="noopener noreferrer"&gt;Reference Architecture Repository&lt;/a&gt;&lt;/strong&gt; with three key additions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📄 &lt;strong&gt;&lt;a href="https://github.com/Sarony11/agentic-infrastructure-bootstrap/blob/main/docs/cross-org-agent-discovery.md" rel="noopener noreferrer"&gt;The Discovery Protocol
Docs&lt;/a&gt;&lt;/strong&gt;: A deep dive into the JSON schema and discovery mechanics.&lt;/li&gt;
&lt;li&gt;⚙️ &lt;strong&gt;&lt;a href="https://github.com/Sarony11/agentic-infrastructure-bootstrap/blob/main/agent-library/.github/workflows/publish-capabilities.yaml" rel="noopener noreferrer"&gt;Mock CI/CD
Pipeline&lt;/a&gt;&lt;/strong&gt;: An example GitHub Action showing how a team compiles and publishes their capabilities.&lt;/li&gt;
&lt;li&gt;🛠️ &lt;strong&gt;&lt;a href="https://github.com/Sarony11/agentic-infrastructure-bootstrap/blob/main/agent-library/skills/global/discover-domain.md" rel="noopener noreferrer"&gt;Domain Discovery
Skill&lt;/a&gt;&lt;/strong&gt;: A base tool that allows your local agent to query remote domains and learn their capabilities on the fly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Big thanks to the community for pushing this concept further. The evolution from local scripts to standards protocols is exactly what will define the next generation of Agentic Platform Engineering!&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>The Agentic Engineering Manifesto: Why Standards are My New Sovereign Frontier</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Sun, 01 Mar 2026 01:43:15 +0000</pubDate>
      <link>https://dev.to/sarony11/the-agentic-engineering-manifesto-why-standards-are-my-new-sovereign-frontier-339p</link>
      <guid>https://dev.to/sarony11/the-agentic-engineering-manifesto-why-standards-are-my-new-sovereign-frontier-339p</guid>
      <description>&lt;p&gt;For the past few months, I’ve been obsessing over a single question: How do we move past the "AI as a toy" phase and actually integrate it into our production workflows without creating a massive, unmanageable mess?&lt;/p&gt;

&lt;p&gt;As someone deep in the world of Kubernetes, GCP, and GitOps, I’ve realized that the hype around which LLM is "smarter" is a distraction. In 2026, the real battle isn't over tokens; it’s over architecture. If we don't standardize how our agents interact with our infrastructure, we aren't building progress—we are just building a new type of technical debt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the "AI Platform Engineer"
&lt;/h2&gt;

&lt;p&gt;You’ve probably heard the industry talking about AI Platform Engineers. Right now, that role is mostly about "plumbing"—managing GPUs, fine-tuning models, and making sure the inference API is up. It's necessary, but it's narrow.&lt;/p&gt;

&lt;p&gt;I want to take this a step further. I’m defining a new specialization: &lt;strong&gt;The Agentic Platform Engineer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While the AI Platform Engineer focuses on making the model available, I am focused on making the agent actionable. My goal isn't just to give the team a brain in a box; it’s to provide that brain with hands, a set of tools, and a strict "code of conduct" so it can operate safely inside our clusters.&lt;/p&gt;

&lt;h2&gt;
  
  
  My 5 Pillars for Agentic Sovereignty
&lt;/h2&gt;

&lt;p&gt;To achieve this, I’m building my strategy around five core pillars. These aren't just tools; they are the standards that allow us to "own" our automation rather than just renting it from a provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Universal Interface: MCP (Model Context Protocol)
&lt;/h3&gt;

&lt;p&gt;I see MCP as the "USB-C" of our era. I’m moving away from writing custom, brittle connectors for every tool. By building MCP servers, I decouple the agent's "thinking" from the infrastructure's "doing." If I decide to swap Claude for a newer model tomorrow, my K8s and GCP integrations stay exactly the same. That is Sovereignty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Intellectual Capital: Portable Skills (agentskills.io)
&lt;/h3&gt;

&lt;p&gt;I’m tired of senior engineers spending half their day explaining the same rollback procedures. I’m codifying that wisdom into Skills. Using the agentskills.io standard, I can package complex DevOps logic into Markdown/YAML files that any agent can load. I’m essentially cloning my best troubleshooting logic and making it an evergreen asset of the company.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; &lt;a href="https://agentskills.io" rel="noopener noreferrer"&gt;https://agentskills.io&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Digital Constitution: Local Rules (.cursorrules)
&lt;/h3&gt;

&lt;p&gt;Every repo I manage now has a "Law of the Land." Through .cursorrules or .clinerules, I define the architectural boundaries. The agent doesn't have to guess if we prefer functional programming or how we tag our Terraform resources; it’s in the "Constitution." This is Governance at the source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; &lt;a href="https://cursor.directory" rel="noopener noreferrer"&gt;https://cursor.directory&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Resilient Orchestration: Stateful Graphs (LangGraph)
&lt;/h3&gt;

&lt;p&gt;Linear prompts are fine for writing emails, but they fail in production. For high-stakes tasks like production deployments, I use Graphs. Frameworks like LangGraph allow me to build flows with memory, self-correction, and—most importantly—Human-in-the-loop checkpoints. I don't just want an agent that "tries"; I want a system that follows a stateful, auditable path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; &lt;a href="https://langchain-ai.github.io/langgraph" rel="noopener noreferrer"&gt;https://langchain-ai.github.io/langgraph&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The Org Chart: Agent Swarms
&lt;/h3&gt;

&lt;p&gt;I’ve realized that a single "god-agent" is a recipe for hallucinations. The future is Swarms. I’m architecting teams of specialists: one agent monitors the logs, another validates the security policy, and a third executes the fix via an MCP tool. It’s about building a digital squad that mirrors a high-performance engineering team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; &lt;a href="https://docs.crewai.com" rel="noopener noreferrer"&gt;https://docs.crewai.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for the Platform Engineering Community
&lt;/h2&gt;

&lt;p&gt;If we just "implement agents," we are following a trend. If we implement standards, we are building a competitive fortress.&lt;/p&gt;

&lt;p&gt;The companies that will lead the next decade aren't the ones with the biggest API credits; they are the ones who own their Agentic Fabric. By specializing as Platform Agentic Engineers, we aren't just managing servers anymore—we are architecting the very intelligence that manages the servers for us.&lt;/p&gt;

&lt;p&gt;We are moving from "writing code" to "governing autonomy." And honestly? There has never been a more exciting time to be in Platform Engineering.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>agents</category>
    </item>
    <item>
      <title>From Terraform to Crossplane: How to Understand Crossplane if you already know Terraform?</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Sun, 01 Feb 2026 18:30:52 +0000</pubDate>
      <link>https://dev.to/sarony11/from-terraform-to-crossplane-how-to-understand-crossplane-if-you-already-know-terraform-3ncn</link>
      <guid>https://dev.to/sarony11/from-terraform-to-crossplane-how-to-understand-crossplane-if-you-already-know-terraform-3ncn</guid>
      <description>&lt;p&gt;If you work in DevOps, &lt;strong&gt;Terraform&lt;/strong&gt; is likely your favorite hammer. It’s reliable, solid, and has built your whole infrastructure (I hope so, at least). But suddenly, you start hearing about &lt;strong&gt;Crossplane&lt;/strong&gt;, and you see diagrams with a thousand Kubernetes cubes, names like &lt;em&gt;XRD&lt;/em&gt; and &lt;em&gt;Compositions&lt;/em&gt;, and your brain just goes &lt;em&gt;click&lt;/em&gt;: &lt;em&gt;"Wait, why are there so many pieces just to do the same thing?"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you feel this way, don’t worry. It’s not that Crossplane is unnecessarily complex; it’s that &lt;strong&gt;we’ve shifted from writing infrastructure "scripts" to creating an "Operating System" for our cloud.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s break it down with the ultimate analogy so you never get lost again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Automated Coffee Shop Analogy
&lt;/h2&gt;

&lt;p&gt;Imagine you want to automate a coffee shop.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;In Terraform:&lt;/strong&gt; You write a step-by-step recipe, execute it, and the kitchen serves a coffee. If someone drinks the coffee or drops the cup, the recipe does nothing until you go back to the kitchen and hit the "Execute" button again.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;In Crossplane:&lt;/strong&gt; You hire a &lt;strong&gt;Barista&lt;/strong&gt; (the Controller) who never stops watching the table. If the coffee disappears, he replaces it instantly without you saying a word. The Barista always ensures that reality matches the menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The "Dictionary" for Terraform Survivors
&lt;/h2&gt;

&lt;p&gt;This is where most people get lost. Let’s translate Crossplane concepts into what you already know from Terraform:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Terraform Element&lt;/th&gt;
&lt;th&gt;Crossplane Element&lt;/th&gt;
&lt;th&gt;What is it really?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Provider Plugin&lt;/strong&gt; (&lt;code&gt;google&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The Brain.&lt;/strong&gt; The binary that knows how to talk to the Google, AWS, or Azure API. This is the expert "Bartista" that knows the secrets of the coffee shop.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;N/A&lt;/strong&gt; (Manual Installation)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CRD (Dictionary)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The Base.&lt;/strong&gt; What teaches Kubernetes what a "CloudRun" or a "Bucket" is. This is the menu of the coffee shop.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Resource&lt;/strong&gt; (&lt;code&gt;google_storage_bucket&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Managed Resource (MR)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The LEGO Piece.&lt;/strong&gt; The smallest, rawest resource that exists in the cloud. This is the coffee cup.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Variables&lt;/strong&gt; (&lt;code&gt;variables.tf&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;XRD (Definition)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The Contract.&lt;/strong&gt; The 4 fields you allow the developer to fill in. This is the form to order the coffee.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Module&lt;/strong&gt; (&lt;code&gt;main.tf&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Composition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The Blueprint.&lt;/strong&gt; The recipe that says: "If I'm asked for X, I'll manufacture Y and Z." This is the recipe to make the coffee.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Module Call&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Claim&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;The Order.&lt;/strong&gt; The ticket left by the developer saying: "I want my coffee." This is the order to make the coffee.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  WHAT actually installs the "atomic" resource?
&lt;/h2&gt;

&lt;p&gt;This is the million-dollar question. How does that Bucket appear out of thin air?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Foundation (Provider):&lt;/strong&gt; This is what we install first. When you install the GCP Provider, the cluster "learns" languages. Before, it only spoke "Kubernetes"; now, it speaks "Google Cloud." It installs the &lt;strong&gt;CRDs&lt;/strong&gt; (the base dictionary).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Blueprint (Composition):&lt;/strong&gt; You, as a platform expert, write a &lt;strong&gt;Composition&lt;/strong&gt;. This is your standard. Here, you decide that all Buckets in your company must be private and located in &lt;code&gt;europe-west3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Order (Claim):&lt;/strong&gt; A developer creates a 5-line YAML (the Claim).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Magic:&lt;/strong&gt; The &lt;strong&gt;Provider&lt;/strong&gt; sees the Claim, checks your &lt;strong&gt;Composition&lt;/strong&gt;, and says: &lt;em&gt;"Okay! I'm going to create the atomic resource (Managed Resource) in Google Cloud right now, based on the Composition."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How does it improve upon my beloved Terraform?
&lt;/h2&gt;

&lt;p&gt;If Terraform already works, why change? This is where Crossplane shines:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Goodbye to "Drift" (Deviation)
&lt;/h3&gt;

&lt;p&gt;In Terraform, if someone manually deletes a resource in the AWS console, your infrastructure stays broken until the next &lt;code&gt;plan/apply&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;In Crossplane, the Provider is watching.&lt;/strong&gt; If you delete the resource, Crossplane recreates it in less than 60 seconds automatically. &lt;strong&gt;Real auto-healing.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Developer Self-Service
&lt;/h3&gt;

&lt;p&gt;Instead of devs asking you for changes in complex Terraform repos, you give them an &lt;strong&gt;interface (XRD)&lt;/strong&gt;. The dev only enters: &lt;code&gt;image: my-app:v1&lt;/code&gt;. They don’t see (and don’t need to see) the 200 lines of network, security, and IAM configuration you’ve hidden inside the &lt;strong&gt;Composition&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A Single Language: YAML
&lt;/h3&gt;

&lt;p&gt;You no longer need to manage states (&lt;code&gt;tfstate&lt;/code&gt;) in remote buckets with complex locks. The state of your infrastructure &lt;strong&gt;is the Kubernetes cluster itself&lt;/strong&gt;. If Kubernetes is alive, your infrastructure is under control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Elephant in the Room: Where is my "Terraform Plan", I F*****g Want to See What is Going to Happen Before It Happens!
&lt;/h2&gt;

&lt;p&gt;Let’s be honest: moving to Crossplane can be terrifying. In Terraform, the &lt;code&gt;plan&lt;/code&gt; is your safety net. You see exactly what will happen before it happens. In Crossplane, you apply a YAML, and the controller starts working. If you accidentally delete a K8s object that represents a Database... &lt;strong&gt;poof&lt;/strong&gt;, your production data could vanish.&lt;/p&gt;

&lt;p&gt;This "fire and forget" nature is what keeps many DevOps away of Crossplane.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Sleep at Night (Solving the State Fear)
&lt;/h3&gt;

&lt;p&gt;Fortunately, there are ways to build a safety net as strong (or stronger) than Terraform’s:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The "Orphan" Policy (Technological)&lt;/strong&gt;: Every Managed Resource in Crossplane has a field called &lt;code&gt;deletionPolicy&lt;/code&gt;. By setting it to &lt;code&gt;Orphan&lt;/code&gt; instead of &lt;code&gt;Delete&lt;/code&gt;, you are telling Crossplane: &lt;em&gt;"If someone deletes this object in Kubernetes, DO NOT touch the resource in the Cloud"&lt;/em&gt;. This is mandatory for Databases and stateful resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArgoCD as your "Plan" (Methodological)&lt;/strong&gt;: If you use GitOps (and you should), ArgoCD provides a visual &lt;strong&gt;Diff&lt;/strong&gt;. Before syncing, you can see exactly what fields will change. It’s your new, visual, and much more readable &lt;code&gt;terraform plan&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deletion Protection (Cloud Native)&lt;/strong&gt;: Just like in Terraform, you should enable &lt;code&gt;deletionProtection: true&lt;/code&gt; on critical resources (SQL, GCS Buckets) at the Provider level. Even if Crossplane tries to delete it, the Cloud Provider will reject the request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finalizers (Kubernetes Native)&lt;/strong&gt;: Kubernetes won't delete an object until its "Finalizers" are cleared. This gives you a window to catch accidental deletions before they reach the Cloud API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Don’t throw Terraform in the trash; it’s still great for static foundations (like creating the Kubernetes cluster itself). But for everything that lives and breathes (databases, queues, cloud apps), &lt;strong&gt;Crossplane is the next level of evolution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You go from being a "script writer" to a &lt;strong&gt;Platform Architect&lt;/strong&gt; offering a catalog of living services to your company.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do you think of using Crossplane? Do you dare to take the leap to the Control Plane or do you use it already?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>crossplane</category>
      <category>terraform</category>
      <category>kubernetes</category>
      <category>gitops</category>
    </item>
    <item>
      <title>Is Terraform for Kubernetes Applications Flawed? For Kubernetes, GitOps is The Way</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Mon, 21 Jul 2025 11:56:59 +0000</pubDate>
      <link>https://dev.to/sarony11/is-terraform-for-kubernetes-applications-flawed-the-case-for-a-gitops-native-future-49ce</link>
      <guid>https://dev.to/sarony11/is-terraform-for-kubernetes-applications-flawed-the-case-for-a-gitops-native-future-49ce</guid>
      <description>&lt;p&gt;As DevOps and platform engineers, we've been rightly conditioned to chant the mantra of "Infrastructure as Code." So, when it comes to deploying applications on Kubernetes, reaching for a familiar tool like Terraform seems logical. It promises a unified workflow to manage everything from VPCs to Helm charts. However, this is a seductive but ultimately flawed path. Using Terraform to manage the lifecycle of Kubernetes-native applications is a significant anti-pattern that creates friction, fragility, and works against the very design principles of Kubernetes itself.&lt;/p&gt;

&lt;p&gt;It's time for a candid discussion. By forcing a tool designed for static infrastructure provisioning onto the dynamic, ever-reconciling world of Kubernetes, we are setting ourselves up for failure. The path to a more resilient, secure, and efficient platform lies in embracing the principles Kubernetes was built for, and that means adopting GitOps.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Clash of Titans: Terraform State vs. Kubernetes Reconciliation
&lt;/h3&gt;

&lt;p&gt;The core of the problem lies in a fundamental conflict of state management. Terraform operates on a discrete, snapshot-based model. It runs, compares the desired state in your HCL code to its stored state file (&lt;code&gt;.tfstate&lt;/code&gt;), and generates a plan to converge the two. It is the undisputed source of truth.&lt;/p&gt;

&lt;p&gt;Kubernetes, however, &lt;em&gt;already has&lt;/em&gt; a powerful state management and reconciliation system. Its control plane continuously works to match the cluster's live state with the desired state declared in its &lt;code&gt;etcd&lt;/code&gt; database. It’s a closed-loop system designed for constant, autonomous correction.&lt;/p&gt;

&lt;p&gt;When you layer Terraform on top of this, you create two competing sources of truth. This inevitably leads to &lt;strong&gt;state drift&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine a scenario: an autoscaler scales your deployment in response to traffic, or an engineer uses &lt;code&gt;kubectl&lt;/code&gt; to debug a pod and changes a label. Terraform knows nothing about these events. Its state file is now a lie, a stale snapshot of a past reality. The next &lt;code&gt;terraform plan&lt;/code&gt; will either report unexpected "drift" that an engineer must manually reconcile or, worse, it could blindly destroy and recreate resources, causing an outage because it tries to "fix" a change that was intentional and necessary. This isn't just inefficient; it's dangerous.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond Provisioning: The Application Lifecycle
&lt;/h3&gt;

&lt;p&gt;Terraform excels at the create-configure-destroy lifecycle of foundational infrastructure. But applications are not static. They are living systems that require sophisticated lifecycle management:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Complex Deployments:&lt;/strong&gt; How do you orchestrate a canary release or a blue-green deployment with Terraform? These patterns are foreign to its resource-centric model.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Rollbacks:&lt;/strong&gt; A rollback in Terraform often means re-running a previous configuration, which can translate to a disruptive destroy-and-recreate cycle. In a Kubernetes-native workflow, a rollback is a rapid, surgical pointer change to a previous ReplicaSet, often completing in seconds.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Observability:&lt;/strong&gt; Terraform provides basic logs, but it can't offer the rich, application-aware status reporting, health checks, and event history that a tool like ArgoCD provides directly from the cluster.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The GitOps Paradigm with ArgoCD: A Better Way
&lt;/h3&gt;

&lt;p&gt;This is where GitOps shines. With a tool like &lt;a href="https://argoproj.github.io/argo-helm" rel="noopener noreferrer"&gt;&lt;strong&gt;ArgoCD&lt;/strong&gt;&lt;/a&gt;, the Git repository becomes the &lt;strong&gt;single, unambiguous source of truth&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The architecture is both simple and powerful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Desired State in Git:&lt;/strong&gt; All manifests (Helm charts, Kustomizations, etc.) for your application are stored in a Git repository.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Continuous Reconciliation:&lt;/strong&gt; The ArgoCD agent runs in your cluster, continuously comparing the live state against the desired state in Git.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Automatic Drift Correction:&lt;/strong&gt; If it detects any deviation—whether from a manual &lt;code&gt;kubectl&lt;/code&gt; change or a configuration error—it can automatically self-heal, reverting the cluster to the state defined in Git.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every change, from a simple image tag update to a full-scale deployment, is managed through a pull request. This workflow provides a natural audit trail, enables peer review for operational changes, and empowers developers to manage their applications' lifecycles using the tools they already know and use.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Final Frontier: What About Infrastructure Dependencies?
&lt;/h3&gt;

&lt;p&gt;This is where the debate gets interesting. "Okay," you might say, "GitOps for the app, but I still need Terraform to create the app's S3 bucket, IAM role, or Cloud SQL database." This forces teams to manage application dependencies in separate repositories and pipelines, creating a new kind of fragmentation.&lt;/p&gt;

&lt;p&gt;This is where we must distinguish between two classes of infrastructure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Core Infrastructure:&lt;/strong&gt; These are the foundational pillars of your platform. VPCs, Kubernetes clusters themselves, DNS zones, and top-level IAM policies. They have a massive blast radius and a slow change cadence. &lt;strong&gt;This is the perfect use case for Terraform.&lt;/strong&gt; Its deliberate, plan-and-apply workflow is a feature, not a bug, when managing these critical resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infrastructure Dependencies:&lt;/strong&gt; These are resources tightly coupled to a single application. They should be created when the app is deployed and destroyed when it's removed. An S3 bucket for a specific microservice, a Pub/Sub topic for an event-driven workflow, or an IAM role for a single pod are prime examples.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Managing these dependencies with Terraform is clumsy. Why should an application team have to file a ticket or run a separate pipeline just to get a bucket?&lt;/p&gt;

&lt;h3&gt;
  
  
  Unifying the Stack with Crossplane and GitOps
&lt;/h3&gt;

&lt;p&gt;This is where a tool like &lt;strong&gt;Crossplane&lt;/strong&gt; completes the GitOps picture. Crossplane extends the Kubernetes API, allowing you to manage external resources as if they were native Kubernetes objects.&lt;/p&gt;

&lt;p&gt;By installing a Crossplane provider for your cloud, you can define an &lt;code&gt;S3Bucket&lt;/code&gt; or &lt;code&gt;RDSPostgreSQLInstance&lt;/code&gt; directly in YAML, right alongside your &lt;code&gt;Deployment&lt;/code&gt; and &lt;code&gt;Service&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, the magic happens. You can place your application's Helm chart &lt;em&gt;and&lt;/em&gt; its Crossplane dependency manifests in the same Git repository. ArgoCD, already watching that repo, will deploy everything in one go.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; ArgoCD applies the manifests.&lt;/li&gt;
&lt;li&gt; The Kubernetes API server receives the &lt;code&gt;Deployment&lt;/code&gt; and the &lt;code&gt;S3Bucket&lt;/code&gt; objects.&lt;/li&gt;
&lt;li&gt; The Kubernetes scheduler deploys the application pods.&lt;/li&gt;
&lt;li&gt; The Crossplane controller sees the &lt;code&gt;S3Bucket&lt;/code&gt; object and provisions the actual bucket in your cloud provider.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The entire application stack, from its cloud dependencies to its Kubernetes configuration, is now a self-contained unit, managed through a single Git repository and a unified GitOps workflow. When you delete the ArgoCD application, it can trigger the deletion of the Kubernetes resources and instruct Crossplane to de-provision the corresponding cloud infrastructure, ensuring a clean, complete teardown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion: Use the Right Tool for the Job
&lt;/h3&gt;

&lt;p&gt;Using Terraform to manage Kubernetes applications is not just a matter of preference; it's a fundamental architectural mismatch. It's like using a screwdriver to hammer a nail—you might eventually get it in, but the process will be awkward, and the result will be fragile.&lt;/p&gt;

&lt;p&gt;The path to a mature, scalable, and secure Kubernetes platform is clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Use Terraform for what it excels at:&lt;/strong&gt; Provisioning and managing your stable, core infrastructure.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Use GitOps with ArgoCD&lt;/strong&gt; for deploying and managing the dynamic lifecycle of your applications.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Use Crossplane alongside ArgoCD&lt;/strong&gt; to manage application-specific infrastructure dependencies, creating truly self-contained and portable application definitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By separating these concerns and embracing a cloud-native, GitOps-centric approach, we can build platforms that are not only more powerful but also more resilient, secure, and easier to maintain. It’s time to stop fighting the current and let Kubernetes be Kubernetes.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>argocd</category>
      <category>gitops</category>
      <category>crossplane</category>
    </item>
    <item>
      <title>HPA vs. KEDA in Kubernetes - The Autoscaling Guide to Know When and Where to Use Them</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Sun, 01 Oct 2023 12:15:46 +0000</pubDate>
      <link>https://dev.to/sarony11/hpa-vs-keda-in-kubernetes-the-autoscaling-guide-to-know-when-and-where-to-use-them-m96</link>
      <guid>https://dev.to/sarony11/hpa-vs-keda-in-kubernetes-the-autoscaling-guide-to-know-when-and-where-to-use-them-m96</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hey there! Remember the first time you got your hands on Kubernetes? Ah, the good ol' days. I was so green back then that I thought Horizontal Pod Autoscaling (HPA) was the be-all and end-all for scaling in Kubernetes. I mean, it was like discovering fire; it felt like I had this incredible tool that could solve all my scalability problems.&lt;/p&gt;

&lt;p&gt;Fast forward a bit, and I landed roles where KEDA was the star of the show, especially in machine learning event-driven applications. We were using RabbitMQ queue metrics to scale our ML consumers like a charm. It was like going from a bicycle to a sports car in the world of autoscaling.&lt;/p&gt;

&lt;p&gt;Now, in my current gig, we started off with HPA, just like old times. But as we scaled and our needs evolved, we found ourselves hitting the same limitations I'd discovered years ago. That's when we decided to bring KEDA into the mix, and let me tell you, it's been a game-changer.&lt;/p&gt;

&lt;p&gt;So why am I telling you all this? Because I want to share these hard-earned lessons with you. In this article, we're going to dissect HPA and KEDA, compare their strengths and weaknesses, and dive into real-world scenarios. My goal is to arm you with the knowledge to make informed decisions right from the get-go, so you know exactly when to use HPA and when to switch gears to KEDA.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is HPA?
&lt;/h3&gt;

&lt;p&gt;HPA automatically adjusts the number of pod replicas in a deployment or replica set based on observed metrics like CPU or memory usage. You set a target—like 70% CPU utilization—and HPA does the rest, scaling the pods in or out to maintain that level. It's like putting your scaling operations on cruise control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Was HPA Devised?
&lt;/h3&gt;

&lt;p&gt;Back in the day, before the cloud-native era, scaling was often a manual and painful process. You'd have to provision new servers, configure them, and then deploy your application. This was time-consuming, error-prone, and not very agile.&lt;/p&gt;

&lt;p&gt;When Kubernetes came along, it revolutionized how we think about deploying and managing applications. But Kubernetes needed a way to handle automatic scaling to truly make the platform dynamic and responsive to the actual needs of running applications. That's where HPA comes in.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: HPA is designed to be simple and straightforward. You don't need a Ph.D. in distributed systems to set it up. Just specify the metric and the target, and you're good to go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Efficiency&lt;/strong&gt;: Before autoscaling, you'd often over-provision resources to handle potential spikes in traffic, which is wasteful. HPA allows you to use resources more efficiently by scaling based on actual needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operational Ease&lt;/strong&gt;: With HPA, the operational burden is reduced. You don't have to wake up in the middle of the night to scale your application manually; HPA has got your back.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-In Metrics&lt;/strong&gt;: Initially, HPA was designed to work with basic metrics like CPU and memory, which are often good enough indicators for many types of workloads.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, in a nutshell, HPA was devised to make life easier for DevOps folks like us, allowing for more efficient use of resources and simplifying operational complexities. It's like the Swiss Army knife of Kubernetes scaling for straightforward use-cases. What do you think? Want to dive deeper into any aspect of HPA?&lt;/p&gt;

&lt;h3&gt;
  
  
  So... When to Use HPA?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Predictable Workloads:&lt;/strong&gt; If you're dealing with an application that has a fairly predictable pattern—like a web app that gets more traffic during the day and less at night—HPA is a solid choice. You can set it to scale based on CPU or memory usage, which are often good indicators of load for these types of apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple Metrics:&lt;/strong&gt; HPA is great when you're looking at straightforward metrics like CPU and memory. If you don't need to scale based on more complex or custom metrics, HPA is easier to set up and manage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quick Setup:&lt;/strong&gt; If you're in a situation where you need to get autoscaling up and running quickly, HPA is your friend. Being a native Kubernetes feature, it's well-documented and supported, making it easier to implement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stateless Applications:&lt;/strong&gt; HPA is particularly well-suited for stateless applications where each pod is interchangeable. This makes it easier to scale pods in and out without worrying about maintaining state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-In Kubernetes Support:&lt;/strong&gt; Since HPA is a built-in feature, it comes with the advantage of native integration into the Kubernetes ecosystem, including monitoring and logging through tools like Prometheus and Grafana.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What is KEDA?
&lt;/h3&gt;

&lt;p&gt;KEDA stands for Kubernetes Event-Driven Autoscaling. Unlike HPA, which is more about scaling based on system metrics like CPU and memory, KEDA is designed to scale your application based on events. These events could be anything from the length of a message queue to the number of unprocessed database records.&lt;/p&gt;

&lt;p&gt;KEDA works by deploying a custom metric server and custom resources in your Kubernetes cluster. It then integrates with various event sources like Kafka, RabbitMQ, Azure Event Hubs, and many more, allowing you to scale your application based on metrics from these systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Was KEDA Devised?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event-Driven Architectures&lt;/strong&gt;: Modern applications are increasingly adopting event-driven architectures, where services communicate asynchronously through events. Traditional autoscalers like HPA aren't designed to handle this kind of workload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complex Metrics&lt;/strong&gt;: While HPA is great for simple metrics, what if you need to scale based on the length of a Kafka topic or the number of messages in an Azure Queue? That's where KEDA comes in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero to N Scaling&lt;/strong&gt;: One of the coolest features of KEDA is its ability to scale your application back to zero when there are no events to process. This can lead to significant cost savings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;: KEDA is designed to be extensible, allowing you to write your own scalers or use community-contributed ones. This makes it incredibly flexible and adaptable to various use-cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-Cloud and On-Premises&lt;/strong&gt;: KEDA supports a wide range of event sources, making it suitable for both cloud and on-premises deployments.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Gap that KEDA Fills Over HPA
&lt;/h3&gt;

&lt;p&gt;While HPA is like your reliable sedan, KEDA is more like a tricked-out sports car with all the bells and whistles. It was devised to fill the gaps left by HPA, particularly for applications that are event-driven or that require scaling based on custom or external metrics.&lt;/p&gt;

&lt;p&gt;So, if you're dealing with complex, event-driven architectures, or if you need to scale based on metrics that HPA doesn't support out of the box, KEDA is your go-to. It's like the next evolution in Kubernetes autoscaling, designed for the complexities of modern, cloud-native applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Real Cases for Using HPA Over KEDA
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Basic Web Application
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: You're running a simple web application that serves static content and has predictable spikes in traffic, like during a marketing campaign.&lt;/p&gt;

&lt;p&gt;In this case, the scaling needs are straightforward and based on CPU or memory usage. HPA is easier to set up and manage for this kind of scenario. You don't need the event-driven capabilities that KEDA offers.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Internal Business Application
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: You have an internal application used by employees for tasks like data entry, which sees higher usage during business hours and lower usage otherwise.&lt;/p&gt;

&lt;p&gt;Again, the load pattern is predictable and can be managed easily with simple metrics like CPU and memory. HPA's native integration with Kubernetes makes it a straightforward choice, without the need for the more complex setup that KEDA might require.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Stateless Microservices
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: You're running a set of stateless microservices that handle tasks like authentication, logging, or caching. These services have a consistent load and don't rely on external events.&lt;/p&gt;

&lt;p&gt;These types of services often scale well based on system metrics, making HPA a good fit. Since they're stateless, scaling in and out is less complex, and HPA can handle it easily.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Traditional RESTful API
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: You have a RESTful API that serves mobile or web clients. The API has a steady rate of requests but might experience occasional spikes.&lt;/p&gt;

&lt;p&gt;In this case, you can set up HPA to scale based on request rates or CPU usage, which are good indicators of load for this type of application. KEDA's event-driven scaling would be overkill for this scenario.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Choose HPA in These Cases?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: HPA is easier to set up and manage for straightforward scaling needs. If you don't need to scale based on complex or custom metrics, HPA is the way to go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Support&lt;/strong&gt;: Being a built-in Kubernetes feature, HPA has native support and a broad community, making it easier to find help or resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Efficiency&lt;/strong&gt;: For applications with predictable workloads, HPA allows you to efficiently use your cluster resources without the need for more complex scaling logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operational Ease&lt;/strong&gt;: HPA requires less ongoing maintenance and has fewer components to manage compared to KEDA, making it a good choice for smaller teams or simpler applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Real Cases for Using KEDA Over HPA
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Event-Driven ML Inference
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: You have a machine learning application for real-time fraud detection. Transactions are events funneled into an AWS SQS queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why KEDA Over HPA&lt;/strong&gt;: With KEDA, you can dynamically adjust the number of inference pods based on the SQS queue length, ensuring timely fraud detection. HPA's system metrics like CPU or memory wouldn't be as effective for this use-case.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. IoT Data Processing
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: Your IoT application collects sensor data that's sent to an Azure Event Hub for immediate processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why KEDA Over HPA&lt;/strong&gt;: Here, KEDA's strength lies in its ability to adapt to the number of unprocessed messages in the Azure Event Hub, ensuring real-time data processing. Traditional HPA scaling based on CPU or memory wouldn't be as responsive to these event-driven requirements.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Real-time Chat Application
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: You manage a chat application where messages are temporarily stored in a RabbitMQ queue before being delivered to users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why KEDA Over HPA&lt;/strong&gt;: KEDA excels in this scenario by dynamically adjusting resources based on the RabbitMQ queue length, ensuring prompt message delivery. This is a level of granularity that HPA, with its focus on system metrics, can't offer.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Stream Processing with Kafka
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: Your application consumes messages from a Kafka topic, and the rate of incoming messages can fluctuate significantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why KEDA Over HPA&lt;/strong&gt;: In this case, KEDA's ability to scale based on the Kafka topic length allows it to adapt to varying loads effectively. HPA, which isn't designed for such custom metrics, wouldn't be as agile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Choose KEDA in These Cases?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event-Driven Flexibility&lt;/strong&gt;: KEDA is tailored for scenarios where system metrics aren't the best indicators for scaling, offering a more nuanced approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Metrics Support&lt;/strong&gt;: Unlike HPA, KEDA can interpret a wide range of custom metrics, making it versatile for complex scaling needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Optimization&lt;/strong&gt;: KEDA's ability to scale down to zero pods when idle can lead to significant cost savings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adaptability&lt;/strong&gt;: The platform's extensible design allows for custom scalers, making it adaptable to a wide range of use-cases.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So there you have it, folks! We've journeyed through the world of Kubernetes autoscaling, dissecting both HPA and KEDA to understand their strengths, limitations, and ideal use-cases. From my early days of being enamored with HPA's simplicity to discovering the event-driven magic of KEDA, it's been a ride full of lessons.&lt;/p&gt;

&lt;p&gt;If you're dealing with predictable workloads and need a quick, straightforward solution, HPA is your reliable workhorse. It's like your trusty old hammer; it might not have all the bells and whistles, but it gets the job done efficiently.&lt;/p&gt;

&lt;p&gt;On the flip side, if your application lives in the fast-paced realm of event-driven architectures or requires scaling based on custom metrics, KEDA is your Swiss Army knife. It's built for the complexities and nuances of modern, cloud-native applications.&lt;/p&gt;

&lt;p&gt;Remember, choosing between HPA and KEDA isn't about which is better overall, but which is better for your specific needs. So take stock of your application's requirements, your team's expertise, and your long-term scaling strategy before making the call.&lt;/p&gt;

&lt;p&gt;As you venture into your next Kubernetes project, I hope this guide serves as a useful roadmap for your autoscaling decisions. And hey, since you're all about diving deeper, maybe explore setting up these autoscaling strategies in a hands-on way. Trust me, there's no better teacher than experience.&lt;/p&gt;

&lt;p&gt;Happy scaling!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Track: Meet VPA
&lt;/h2&gt;

&lt;p&gt;While we've focused on HPA and KEDA, let's not forget about the Vertical Pod Autoscaler (VPA). Unlike HPA and KEDA, which scale the number of pod replicas, VPA adjusts the CPU and memory resources for your existing pods. Think of it as making your pods beefier or leaner based on their actual needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Consider VPA?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Optimization&lt;/strong&gt;: VPA fine-tunes the CPU and memory allocated to each pod, helping you use cluster resources more efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complementary&lt;/strong&gt;: VPA can work alongside HPA or KEDA, offering another layer of autoscaling. While HPA and KEDA scale out, VPA scales up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stateful Apps&lt;/strong&gt;: For applications that can't be easily scaled horizontally, like stateful services, VPA can be a better fit.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, as you ponder your autoscaling strategy, keep VPA in your back pocket. It offers a different angle on scalability that might just be what your project needs.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>keda</category>
      <category>autoscaling</category>
      <category>guide</category>
    </item>
    <item>
      <title>Rethinking Infrastructure as Code: The Second Wave of DevOps and IaC by Winglang</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Tue, 26 Sep 2023 00:37:14 +0000</pubDate>
      <link>https://dev.to/sarony11/rethinking-infrastructure-as-code-the-second-wave-of-devops-and-iac-by-winglang-dnj</link>
      <guid>https://dev.to/sarony11/rethinking-infrastructure-as-code-the-second-wave-of-devops-and-iac-by-winglang-dnj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Picture this: You're sitting at your desk, sifting through lines of Terraform code, and you can't shake the feeling that something's off. It's like you're trying to assemble a puzzle, but the pieces keep changing shapes. Then, you stumble upon an &lt;a href="https://nathanpeck.com/rethinking-infrastructure-as-code-from-scratch/" rel="noopener noreferrer"&gt;article by Nathan Peck&lt;/a&gt;, and it's like someone turned on a light. Nathan's words resonate with you, articulating the unease you've felt but couldn't put into words. It's time for a change—a second wave in DevOps and IaC. And as you'll soon discover, Winglang might just be the surfboard we all need to ride this wave.&lt;/p&gt;

&lt;p&gt;The DevOps and Infrastructure as Code (IaC) landscapes have seen significant advancements over the years. However, as cloud ecosystems grow in complexity, so do the tools and practices we use. Nathan Peck's article on rethinking IaC and the "Second Wave DevOps" piece from System Initiative both point to the need for a new approach. Enter Winglang, a cloud-oriented programming language that promises to simplify the cloud development process. Could this be the future of DevOps and IaC? Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Current State of DevOps and IaC
&lt;/h2&gt;

&lt;p&gt;DevOps has come a long way since its inception, with best practices like CI/CD, feature flags, and shared observability becoming the norm. However, despite these advancements, 88% of companies still can't deploy more than once a week. Similarly, IaC tools like Terraform and CloudFormation have become increasingly complex, making them hard to manage and scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problems
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Complexity&lt;/strong&gt;: Both DevOps and IaC are grappling with the complexities of modern cloud services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stagnation&lt;/strong&gt;: The tools and practices have evolved, but the overall system design hasn't kept pace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Experience&lt;/strong&gt;: DevOps work is often filled with "tiny papercuts," making it the worst part of building a modern application.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Need for a Second Wave: A Closer Look
&lt;/h2&gt;

&lt;p&gt;The DevOps and IaC landscapes are at a crossroads. While the tools and practices have evolved, the overall system design hasn't kept pace with the complexities of modern cloud services. Two thought-provoking articles—&lt;a href="https://nathanpeck.com/rethinking-infrastructure-as-code-from-scratch/" rel="noopener noreferrer"&gt;Nathan Peck's "Rethinking Infrastructure as Code from Scratch"&lt;/a&gt; and &lt;a href="https://www.systeminit.com/blog-second-wave-devops" rel="noopener noreferrer"&gt;System Initiative's "Second Wave DevOps"&lt;/a&gt;—highlight the need for a new approach. Let's delve into each.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nathan Peck's CSS for IaC: Simplifying Complexity
&lt;/h3&gt;

&lt;p&gt;Nathan Peck argues that as cloud services grow in complexity, the IaC tools we use are becoming increasingly complex and unmanageable. He suggests that we need a new approach to make IaC more scalable, maintainable, and easier to understand.&lt;/p&gt;

&lt;h4&gt;
  
  
  The CSS Analogy
&lt;/h4&gt;

&lt;p&gt;Nathan draws an analogy with HTML and CSS in web development. Just like CSS allows you to separate styling from content, he proposes a similar layer for IaC. This layer would let you group configurations into "traits" that you can apply to multiple resources.&lt;/p&gt;

&lt;h4&gt;
  
  
  Benefits of Traits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easier to Read&lt;/strong&gt;: Semantic names for configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale Expertise&lt;/strong&gt;: Senior devs can create these traits, and junior devs can apply them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centrally Updatable&lt;/strong&gt;: Change the trait in one place, and it updates everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean Removal&lt;/strong&gt;: Removing a trait removes all its settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  System Initiative's Second Wave DevOps: Rethinking System Design
&lt;/h3&gt;

&lt;p&gt;The "Second Wave DevOps" article takes a broader view, focusing not just on IaC but on the entire DevOps landscape. It argues that despite the cultural shift towards DevOps, the tools and practices have not evolved to meet the complexities of today's cloud ecosystems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Stagnation Problem&lt;/strong&gt;: The article points out that what worked for John Allspaw and Paul Hammond in 2009 is, in broad strokes, what we have been asking every single DevOps practitioner to do since. We've optimized individual parts of the system but haven't rethought how the whole system is put together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Call for a System Overhaul&lt;/strong&gt;: The article calls for a "second wave" of DevOps tools that focus on improving the daily experience of DevOps work. It's not just about automating tasks but reimagining the entire workflow and system design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Risk of Not Changing&lt;/strong&gt;: If we don't adapt, we risk the DevOps culture itself. The failure of our implementations could put the success of our culture change at risk, taking us back to a time when DevOps didn't exist, which was unequivocally worse for everyone involved.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.winglang.io/docs" rel="noopener noreferrer"&gt;Enter Winglang&lt;/a&gt;: A Cloud-Oriented Programming Language
&lt;/h2&gt;

&lt;p&gt;As we grapple with the complexities and challenges in the DevOps and IaC landscapes, Winglang emerges as a potential game-changer. Designed to abstract away the intricacies of underlying cloud infrastructure, it allows developers to focus on what matters most: the application logic. But what makes Winglang stand out? Let's dissect its key features and see how it could be a cornerstone in the second wave of DevOps and IaC.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Philosophy of Cloud-Oriented Programming
&lt;/h3&gt;

&lt;p&gt;Winglang is built on the philosophy of "cloud-oriented programming," a paradigm that treats the cloud as a single, unified computer. This approach heavily relies on managed services and distributed programming to build systems that are intrinsically scalable, highly-available, and robust. It's a shift from seeing the cloud as a collection of services to viewing it as an integrated computing environment.&lt;/p&gt;

&lt;p&gt;This philosophy aligns well with the calls for a second wave in DevOps and IaC. By treating the cloud as a unified system, Winglang inherently addresses many of the complexities and "tiny papercuts" that DevOps engineers face daily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=wzqCXrsKWbo" rel="noopener noreferrer"&gt;Watch Winglang Quick Introduction Video&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Winglang Key Elements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High-Level Cloud Primitives: The Batteries-Included Approach:&lt;/strong&gt; One of Winglang's standout features is its high-level cloud primitives. These are essentially pre-built, cloud-portable resources that you can plug into your application, much like importing a library in traditional programming languages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Power of Abstraction:&lt;/strong&gt; These high-level primitives allow developers to leverage the full extent of the cloud without having to be infrastructure experts. It's akin to Nathan Peck's idea of using CSS-like "traits" to simplify configurations, but Winglang takes it a step further by integrating these abstractions directly into the programming language.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local Cloud Simulator Developer's Dream&lt;/strong&gt;: Winglang comes with a local cloud simulator, allowing you to run your applications locally. This is a game-changer for debugging, testing, and iterative development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Speed of Iteration:&lt;/strong&gt; The local cloud simulator enables developers to see the effects of incremental changes at milliseconds latency. This aligns with the "Second Wave DevOps" article's call for tools that improve the daily experience of DevOps work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Infrastructure as Policy: A Horizontal Approach:&lt;/strong&gt; Winglang introduces the concept of "Infrastructure as Policy," where infrastructure concerns like deployment, networking, and security can be applied horizontally through policies, rather than being hardcoded into the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Benefit of Separation:&lt;/strong&gt; This feature allows for a clean separation between application logic and infrastructure concerns, making the codebase easier to manage and scale. It's a practical implementation of the "second wave" philosophy that calls for a complete overhaul of system design.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The complexities of modern cloud ecosystems demand a new approach to DevOps and IaC. Whether it's Nathan Peck's idea of CSS for IaC, System Initiative's call for a second wave in DevOps, or Winglang's cloud-oriented programming, it's clear that we're on the cusp of a significant shift in how we approach cloud development and operations.&lt;/p&gt;

&lt;p&gt;Winglang seems to encapsulate many of the ideas and needs expressed by thought leaders like Nathan Peck and System Initiative. By offering a new way to approach cloud development, it could very well be a key player in the next wave of DevOps and IaC innovations.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>iac</category>
      <category>discuss</category>
      <category>cloud</category>
    </item>
    <item>
      <title>NGINX vs. Traefik vs. Istio — Unlocking the Secrets to Mastering Kubernetes Ingress</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Mon, 25 Sep 2023 19:02:54 +0000</pubDate>
      <link>https://dev.to/sarony11/istio-vs-traefik-vs-nginx-unlocking-the-secrets-to-mastering-kubernetes-ingress-40d</link>
      <guid>https://dev.to/sarony11/istio-vs-traefik-vs-nginx-unlocking-the-secrets-to-mastering-kubernetes-ingress-40d</guid>
      <description>&lt;p&gt;Let's be real, navigating the kubernetes ecosystem can feel like you're threading a labyrinth. One wrong turn, and you're staring down a Minotaur of complexity. That's why today, we're zeroing in on one of the most crucial decisions you'll make in your Kubernetes journey: selecting the right ingress controller.&lt;/p&gt;

&lt;p&gt;We're pitting NGINX, Traefik and Istio against each other in an epic showdown. Why? Because your ingress controller is more than just a traffic cop; it's the gateway to your application, the bouncer at your club, and the guardian of your microservices.&lt;/p&gt;

&lt;p&gt;So, whether you're architecting a sprawling microservices empire, scaling a dynamic cloud-native startup, or running a rock-solid enterprise application, this guide is your treasure map. We'll dissect features, complexity, performance, and community support to help you make an expert-level decision.&lt;/p&gt;

&lt;p&gt;Ready to become the Gandalf of Kubernetes ingress? Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Picture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.nginx.com/products/nginx-ingress-controller/" rel="noopener noreferrer"&gt;NGINX&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;NGINX is the granddaddy of reverse proxies. It's been around for ages and is super stable. As an ingress controller, it's straightforward but might lack some of the dynamic features of the other two. It's like the established corporation that's been doing its thing for years.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://doc.traefik.io/traefik/providers/kubernetes-ingress/" rel="noopener noreferrer"&gt;Traefik&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Traefik is the new kid on the block, designed to be cloud-native and super dynamic. It's easier to get started with and has some neat features like automated SSL certificate management. It's like that cool, agile startup that's disrupting the market.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://istio.io/latest/docs/tasks/traffic-management/ingress/kubernetes-ingress/" rel="noopener noreferrer"&gt;Istio&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Think of Istio as a combination of service mesh and ingress. It's a full-blown service mesh that can handle traffic routing, security, and more. It's like a "do-it-all" solution but comes with a steeper learning curve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Differences
&lt;/h2&gt;

&lt;p&gt;So, you've got the 30,000-foot view of Istio, Traefik, and NGINX. But let's face it, the devil's in the details, right? In this section, we're diving into the key differentiators that set these ingress controllers apart. We'll explore complexity, features, performance, and community support, so you can make an informed choice that fits like a glove.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexity &amp;amp; Learning Curve
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;NGINX&lt;/strong&gt;: Low. It's straightforward but less dynamic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traefik&lt;/strong&gt;: Moderate. Easier to get up and running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Istio&lt;/strong&gt;: High. You'll need to invest time to understand its many features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NGINX&lt;/strong&gt;: Basic load balancing, SSL termination, and routing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traefik&lt;/strong&gt;: Dynamic reconfiguration, middleware support, and automated SSL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Istio&lt;/strong&gt;: Traffic routing, fault injection, circuit breaking, and a lot more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NGINX&lt;/strong&gt;: Battle-tested and optimized for performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traefik&lt;/strong&gt;: Generally lighter and designed for cloud-native environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Istio&lt;/strong&gt;: Can be resource-intensive because of its extensive features.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Community &amp;amp; Ecosystem
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NGINX&lt;/strong&gt;: Huge community but more in the general web server space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traefik&lt;/strong&gt;: Growing community, especially in the cloud-native space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Istio&lt;/strong&gt;: Strong backing by Google and IBM.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use Which?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenarios for NGINX
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stability &amp;amp; Maturity&lt;/strong&gt;: Ideal for setups that require a tried-and-true solution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example: Enterprise Web Application&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You're in charge of an enterprise-level web application that has been running for years. Stability and performance are key. NGINX, being a mature and well-optimized solution, can provide the reliability you need.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;: If raw HTTP/HTTPS routing performance is a priority, NGINX is highly optimized.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example: Content Delivery Network (CDN)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You're running a CDN and need raw HTTP/HTTPS routing performance. NGINX is highly optimized for these kinds of workloads and can handle massive amounts of traffic with lower latency.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scenarios for Traefik
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Environments&lt;/strong&gt;: Perfect for cloud-native setups where services frequently scale.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example: Media Streaming Service&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You're running a media streaming service like Netflix, where the demand can spike unpredictably during new releases. Services need to be dynamically scaled. Traefik can automatically discover and route traffic to these new instances without manual intervention.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quick Start&lt;/strong&gt;: If you want to get up and running quickly, Traefik is your friend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example: Startup MVP&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You're a startup aiming to quickly launch an MVP for a food delivery app. You don't have the luxury of time to go through extensive documentation. Traefik allows you to get your ingress routing up and running quickly, so you can focus on iterating your app.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scenarios for Istio
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Complex Microservices&lt;/strong&gt;: Istio shines in environments with multiple services that need advanced routing and security features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example: Financial Trading Platform&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Imagine you're running a complex financial trading platform where multiple microservices are responsible for things like trade execution, risk assessment, and real-time analytics. You need advanced routing, security features, and observability. Istio can manage the service-to-service communication, enforce security policies, and provide detailed metrics and tracing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advanced Traffic Routing&lt;/strong&gt;: Need canary deployments or A/B testing? Istio is your go-to.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example: E-commerce Platform&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;You have an e-commerce platform and want to roll out a new recommendation engine. With Istio, you can set up canary deployments to slowly introduce the new feature to a subset of users, monitor its performance, and roll it back if things go south.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Choosing between Istio, Traefik, and NGINX boils down to your specific needs and the complexity of your environment. Each has its own set of features, advantages, and trade-offs. So, what's it gonna be? Pick your weapon of choice and may the Kube be with you!&lt;/p&gt;

</description>
      <category>istio</category>
      <category>kubernetes</category>
      <category>nginx</category>
      <category>traefik</category>
    </item>
    <item>
      <title>Unlocking the Power of Code Documentation with AskTheCode for ChatGPT4</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Sat, 02 Sep 2023 12:46:02 +0000</pubDate>
      <link>https://dev.to/sarony11/unlocking-the-power-of-code-documentation-with-askthecode-for-chatgpt4-1gi9</link>
      <guid>https://dev.to/sarony11/unlocking-the-power-of-code-documentation-with-askthecode-for-chatgpt4-1gi9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hey there, fellow DevOps enthusiast! Ever found yourself drowning in a sea of GitHub repositories, trying to make sense of codebases that look like a labyrinth? Or maybe you're tasked with onboarding new team members, and you wish there was a way to make the process smoother? Well, let me introduce you to the AskTheCode ChatGPT4 plugin. This bad boy is designed to bridge the gap between ChatGPT and GitHub repositories, making your life a lot easier. Stick around, and I'll break down why you should use it, how to get started, and even throw in some real-world examples using the official Kubernetes repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;AskTheCode is a ChatGPT4 plugin that helps you interact with GitHub repositories. It supports multiple programming languages and can work with both public and private repos. It's a game-changer for code documentation, onboarding new team members, and much more. You can install it directly from ChatGPT and start using it straight away, having the link of your repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  But Why to use AskTheCode in a DevOps and IaC Era?
&lt;/h2&gt;

&lt;p&gt;DevOps is all about automating the software delivery process and improving collaboration between development and operations. Infrastructure as Code (IaC), on the other hand, is about managing and provisioning your cloud resources using code. Both of these domains involve a lot of codebase interaction, code reviews, and collaboration. Here's where AskTheCode can be a lifesaver:&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Reviews Made Easy
&lt;/h3&gt;

&lt;p&gt;In DevOps, code reviews are crucial for maintaining the quality and reliability of the software. AskTheCode can help you quickly understand the logic and structure of pull requests. Imagine asking, "What does this new function in the Terraform script do?" and getting a concise, accurate answer. It's like having a code review assistant.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seamless Onboarding
&lt;/h3&gt;

&lt;p&gt;New team members often struggle with understanding the existing infrastructure setup, especially if it's defined through IaC. AskTheCode can provide quick insights into what each part of the code does, making the onboarding process smoother. You could ask, "Explain the AWS setup in this Ansible playbook," and get a straightforward explanation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation Gaps
&lt;/h3&gt;

&lt;p&gt;DevOps and IaC often suffer from poor or outdated documentation due to the fast-paced nature of changes. AskTheCode can help identify these gaps. You could ask, "Is there any missing documentation for this Kubernetes deployment YAML?" and then act on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging and Monitoring
&lt;/h3&gt;

&lt;p&gt;In DevOps, you often need to debug issues in real-time. AskTheCode can help by providing insights into common issues or bugs in the codebase. For example, you could ask, "What are common issues with this Dockerfile?" and get a list of potential pitfalls to avoid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaboration Booster
&lt;/h3&gt;

&lt;p&gt;DevOps is all about collaboration, and AskTheCode can serve as a centralized knowledge base. Team members can ask questions about the codebase and get instant answers, reducing the time spent in back-and-forths and meetings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version Control
&lt;/h3&gt;

&lt;p&gt;In IaC, versioning is crucial. AskTheCode can help you understand the changes between different versions of your infrastructure code. You could ask, "What are the differences between version 1 and version 2 of this Terraform module?" and get a detailed comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use it?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;First things first, you'll need to install the AskTheCode plugin. AskTheCode documentation is clear, so you can follow it -&amp;gt; &lt;a href="https://docs.askthecode.ai/getting-started/prerequisites/" rel="noopener noreferrer"&gt;https://docs.askthecode.ai/getting-started/prerequisites/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Once installed, pick the GitHub repository you want to analyse.&lt;/li&gt;
&lt;li&gt;Finally, start asking ChatGPT questions related to the repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Do We Test It? Using the Official Kubernetes Repository
&lt;/h2&gt;

&lt;p&gt;Alright, let's get our hands dirty with some real-world examples. Imagine you're a newcomer to the kubernetes open source project, working with the &lt;a href="https://github.com/kubernetes/kubernetes" rel="noopener noreferrer"&gt;Kubernetes repository&lt;/a&gt;. Diving into an open source project for the first time can be like stepping into a maze. But don't worry, AskTheCode can be your guide. Here are some questions that would be super helpful for onboarding:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Project Overview&lt;/strong&gt;: "Can you summarize the main components and architecture of the Kubernetes project?"&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This will give you a 10,000-foot view of the project, helping you understand how all the pieces fit together.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;First Steps&lt;/strong&gt;: "What are some good first issues or beginner-friendly tasks in the Kubernetes repository?"&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This can help you find a starting point for contributing to the project, something that's manageable and yet impactful.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Codebase Navigation&lt;/strong&gt;: "How is the codebase organized? Can you highlight the most important directories and files?"&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Knowing where everything is can save you a ton of time. It's like having a map of the labyrinth.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Development Workflow&lt;/strong&gt;: "What's the typical development workflow for contributing to Kubernetes? Are there any specific coding guidelines?"&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understanding the workflow and coding standards can help you integrate seamlessly into the team and contribute more effectively.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So imagine the potential that a tool like this can have in your company, in your team, in your life :P (perhaps I am a bit epic about it, but I am a knowledge base lover and this is gorgeous :P)&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Concerns and Downsides: A Word of Caution 🚨
&lt;/h2&gt;

&lt;p&gt;While AskTheCode offers a plethora of advantages, it's essential to weigh these against some significant security concerns, especially if you're considering using this plugin within a corporate setting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Admin GitHub Privileges: A Red Flag 🚩
&lt;/h3&gt;

&lt;p&gt;One of the most glaring issues is that AskTheCode asks for &lt;a href="https://github.com/askthecode/askthecode.github.io/issues/3" rel="noopener noreferrer"&gt;admin-level GitHub privileges&lt;/a&gt;. From a security standpoint, this is a big no-no. Admin privileges provide extensive access, including the ability to delete repositories, something that most third-party tools shouldn't require. Personally, I find no justification for such elevated access levels, and it raises questions about the plugin's data privacy and security measures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Legal Compliance
&lt;/h3&gt;

&lt;p&gt;Before integrating any third-party tool like AskTheCode, it's crucial to consider its compliance with data protection laws like GDPR or CCPA. This is particularly important if the tool will be interacting with private repositories containing sensitive or proprietary information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internal Policies and Audit Trails
&lt;/h3&gt;

&lt;p&gt;Your company's internal policies may have strict guidelines about third-party integrations. Additionally, the absence of an audit trail feature in AskTheCode makes it difficult to track interactions, which could be a compliance issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;So there you have it! AskTheCode can be a powerful ally in your DevOps journey, making tasks like code documentation and team onboarding a walk in the park. However, given security concerns, I can't recommend using AskTheCode for private company repositories. The risks, in this case, outweigh the benefits.&lt;/p&gt;

&lt;p&gt;Fortunately, it will become in your best ally when used for open-source projects or hobby-related coding, the plugin can be incredibly useful. It offers a quick and efficient way to navigate through codebases, making it a valuable asset for individual developers and contributors in the open-source community.&lt;/p&gt;

&lt;p&gt;Feel free to dive in and explore. Trust me, you won't regret it!&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>documentation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Achieving Zero-Downtime Load Migration in Kubernetes GKE with Autoscaling</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Wed, 30 Aug 2023 14:03:24 +0000</pubDate>
      <link>https://dev.to/sarony11/achieving-zero-downtime-load-migration-in-kubernetes-gke-with-autoscaling-10m2</link>
      <guid>https://dev.to/sarony11/achieving-zero-downtime-load-migration-in-kubernetes-gke-with-autoscaling-10m2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The magic of autoscaling ensures that your application scales seamlessly with demand. But what happens when you need to migrate your workloads from one node pool to another without causing disruptions? In this article, we'll dive into the process of migrating loads between GKE node pools while autoscaling is enabled, all without interrupting your services.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR (Too Long; Didn't Read)
&lt;/h2&gt;

&lt;p&gt;Migrating loads between GKE node pools while keeping autoscaling operational might sound complex, but it's an essential operation in scenarios like resource optimization, maintenance, or refining your scaling strategy. To execute this successfully, you'll:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new node pool: Prepare a destination for your workloads.&lt;/li&gt;
&lt;li&gt;Cordoning nodes: Pause new pod scheduling on nodes in the source node pool.&lt;/li&gt;
&lt;li&gt;Disable autoscaling: Temporarily halt automatic scaling for controlled migration.&lt;/li&gt;
&lt;li&gt;Draining or rolling restarts: Shift running workloads off the source nodes.&lt;/li&gt;
&lt;li&gt;Monitor and validate: Keep an eye on cluster health and application performance.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Do We Need This?
&lt;/h2&gt;

&lt;p&gt;There are a few key scenarios that highlight the importance of seamless load migration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Optimal Resource Utilization:&lt;/strong&gt; New node pools might offer better resources or updated OS versions, making migration crucial for performance optimization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance and Upgrades:&lt;/strong&gt; During system updates or maintenance tasks, smooth load migration ensures continuous availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling Flexibility:&lt;/strong&gt; As your application scales, distributing the load across multiple node pools can help maintain optimal performance without overwhelming individual nodes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step-by-Step Guide
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Create a the New Node Pool&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the Google Cloud Console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to your GKE cluster.&lt;/li&gt;
&lt;li&gt;Under "Cluster," select "Node Pools."&lt;/li&gt;
&lt;li&gt;Click "Create a Node Pool" to set up a destination for your workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, those are steps for doing it manually but if you use IaC with Terraform, just let you know that you have to create the nodepool  as the first step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Cordoning Nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cordoning nodes prevents new pods from being scheduled on nodes in the source node pool. This step prepares the pool for migration while keeping existing workloads running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl cordon NODE_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Disable Autoscaling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By disabling autoscaling, you gain control over the migration process. This ensures that the source node pool won't unexpectedly scale during migration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Google Cloud Console, navigate to your GKE cluster.&lt;/li&gt;
&lt;li&gt;Under "Cluster," select "Node Pools."&lt;/li&gt;
&lt;li&gt;Pick the source node pool and click "Edit."&lt;/li&gt;
&lt;li&gt;Turn off autoscaling and save the changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Draining Nodes or Rolling Restarts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a smooth transition, you can either drain nodes or perform rolling restarts on deployments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Draining Nodes:&lt;/strong&gt; Evict pods gracefully from nodes you're migrating using:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  kubectl drain NODE_NAME &lt;span class="nt"&gt;--ignore-daemonsets&lt;/span&gt; &lt;span class="nt"&gt;--delete-emptydir-data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although draining the node is the most easiest and fast way to evict the pods from one node to other node, this can be impossible if PodDisruptionBudgets are set. If you find any problem related with this, follow with Rolling Restart procedure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rolling Restarts:&lt;/strong&gt; If managed by Deployments, this approach gradually moves pods to other nodes with minimal service disruption. Identify the deployments allocated on the nodes, and rollout restart them.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  kubectl rollout restart DEPLOYMENT_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kubernetes' scheduler automatically places evicted pods onto new nodes in the destination node pool, ensuring minimal downtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Monitor and Validate
&lt;/h2&gt;

&lt;p&gt;Keep a close watch on your GKE cluster to ensure the migration's success. Check the status of your workloads and their performance in the new node pool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Seamlessly migrating loads between GKE node pools with autoscaling enabled might seem intricate, but with careful planning and execution, you can achieve it without service interruptions. GKE empowers you to manage these transitions efficiently as your application evolves, maintaining high availability and performance. Embrace the flexibility and tools GKE offers, and confidently manage your infrastructure's growth and change.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>advance</category>
      <category>operations</category>
    </item>
    <item>
      <title>GitHub - Writting commits like a boss</title>
      <dc:creator>Saul Fernandez</dc:creator>
      <pubDate>Fri, 03 Mar 2023 05:40:19 +0000</pubDate>
      <link>https://dev.to/sarony11/github-writting-commits-like-a-boss-47j</link>
      <guid>https://dev.to/sarony11/github-writting-commits-like-a-boss-47j</guid>
      <description>&lt;p&gt;Writing clear and descriptive commit messages is an important part of the software development process. Good commit messages can help you and your team members better understand the changes made to the codebase, and can also serve as a useful reference for future development work. Here are some golden rules to follow when your commit messages like a f****** boss:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Specify the type of commit&lt;/strong&gt;: At the beginning of the commit, specify the type of change you are doing to easily understand what the commit is about. Every project can use their own conventions, but these works for me.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;feat:     The new feature being added to a particular application&lt;/li&gt;
&lt;li&gt;fix:      A bug fix&lt;/li&gt;
&lt;li&gt;style:    Feature and updates related to styling&lt;/li&gt;
&lt;li&gt;refactor: Refactoring a specific section of the codebase&lt;/li&gt;
&lt;li&gt;test:     Everything related to testing&lt;/li&gt;
&lt;li&gt;docs:     Everything related to documentation&lt;/li&gt;
&lt;li&gt;chore:    Regular code maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Keep it concise&lt;/strong&gt;: Your commit message should be brief and to the point. It should summarize the change made in the commit, but not be too lengthy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the imperative mood&lt;/strong&gt;: Use the imperative mood in your commit message, which means writing in the present tense and using action verbs. For example, "Fix the bug" instead of "Fixed the bug".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If needed, provide more detail in the body&lt;/strong&gt;: To be completely honest, I do not do this so much, but I really do it when doing some kind of squash or a final final final final commit (you know what I mean). In this body I include why the change was necessary, any trade-offs made, and any other relevant information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be consistent&lt;/strong&gt;: Use a consistent style and format for your commit messages throughout the project. This can help make them easier to read and understand.&lt;/p&gt;

&lt;p&gt;If you follow these practices, your teammates will deeply love you, and you will show that are not the regular coder, but an exceptional one.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
