<?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: AGP Marka</title>
    <description>The latest articles on DEV Community by AGP Marka (@agp_marka_62a62d1cdadad70).</description>
    <link>https://dev.to/agp_marka_62a62d1cdadad70</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%2F3781487%2Fda40cd5b-d8d6-4a17-9ae5-5b238141539d.png</url>
      <title>DEV Community: AGP Marka</title>
      <link>https://dev.to/agp_marka_62a62d1cdadad70</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agp_marka_62a62d1cdadad70"/>
    <language>en</language>
    <item>
      <title>I Ran Foundry and Got 6 Docker Containers. So I Broke Into All of Them.</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Sun, 19 Jul 2026 14:42:47 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/i-ran-foundry-and-got-6-docker-containers-so-i-broke-into-all-of-them-118h</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/i-ran-foundry-and-got-6-docker-containers-so-i-broke-into-all-of-them-118h</guid>
      <description>&lt;h1&gt;
  
  
  I Ran Foundry and Got 6 Docker Containers. So I Broke Into All of Them.
&lt;/h1&gt;

&lt;p&gt;Three minutes after running &lt;code&gt;foundryctl cast&lt;/code&gt;, I had 6 Docker containers on my machine and no clue what most of them did. The SigNoz docs explain how to install. They don't tell you what's actually running.&lt;/p&gt;

&lt;p&gt;So I opened every one of them. Read the configs, poked the databases, watched the logs. Here's what I found: a JWT security hole, an OpAMP error loop, and a ClickHouse table with 80+ columns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: The YAML
&lt;/h2&gt;

&lt;p&gt;Foundry needs one file:&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;# casting.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;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;Installation&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;signoz&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;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;
    &lt;span class="na"&gt;flavor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;compose&lt;/span&gt;
  &lt;span class="na"&gt;mcp&lt;/span&gt;&lt;span class="pi"&gt;:&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;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;foundryctl cast &lt;span class="nt"&gt;-f&lt;/span&gt; casting.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Six containers show up:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdggn8srgjdbp195289kj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdggn8srgjdbp195289kj.png" alt="Docker PS showing running containers" width="799" height="107"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;signoz-signoz-0                         signoz/signoz:latest                   Up (healthy)
signoz-ingester-1                       signoz/signoz-otel-collector:latest    Up
signoz-telemetrystore-clickhouse-0-0    clickhouse/clickhouse-server:25.12.5   Up (healthy)
signoz-telemetrykeeper-clickhousekeeper-0 clickhouse/clickhouse-keeper:25.12.5 Up (healthy)
signoz-metastore-postgres-0             postgres:16                            Up (healthy)
signoz-mcp                              signoz/signoz-mcp-server:latest        Up (unhealthy)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All on the same Docker network with static IPs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;172.19.0.2 — ClickHouse Keeper
172.19.0.3 — ClickHouse
172.19.0.4 — Ingester (OTel collector)
172.19.0.5 — PostgreSQL
172.19.0.6 — SigNoz frontend + API
172.19.0.7 — MCP server (unhealthy, stays that way)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwco0tjw50xzpplh4kjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwco0tjw50xzpplh4kjs.png" alt="Docker network inspect showing static IP assignments" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foundry also writes a lock file called &lt;code&gt;casting.yaml.lock&lt;/code&gt; that's 668 lines long. I didn't find it until day two. It has every config, every env var, every IP address. Would have saved me hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First Thing That Went Wrong
&lt;/h2&gt;

&lt;p&gt;I started reading logs immediately. The signoz container couldn't reach PostgreSQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR  failed to connect to user=signoz database=signoz ... connection refused
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It retried 4 times over 16 seconds. PostgreSQL just wasn't ready yet. Same thing happened with the ingester and ClickHouse. The ingester kept trying to connect and failing for about 30 seconds. I watched it spam this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error occurred while checking for sync migrations to complete, retrying
dial tcp: lookup signoz-telemetrystore-clickhouse-0-0: no such host
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything worked eventually. But those first 30 seconds are noisy. If you deploy Foundry and see errors, just wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Actually Inside signoz-signoz-0
&lt;/h2&gt;

&lt;p&gt;This is the main SigNoz binary. &lt;code&gt;./signoz server&lt;/code&gt;. It starts 12 internal services. I counted them from the logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instrumentation, pprof, analytics, alertmanager, ruler,
licensing, auditor, meterreporter, authz, statsreporter,
tokenizer, user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each one is a mini-service inside the same process. Some depend on others: &lt;code&gt;user&lt;/code&gt; waits for &lt;code&gt;authz&lt;/code&gt;, &lt;code&gt;meterreporter&lt;/code&gt; waits for &lt;code&gt;licensing&lt;/code&gt;. I saw these dependency waits in the logs too.&lt;/p&gt;

&lt;p&gt;It connects to two databases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SIGNOZ_SQLSTORE_POSTGRES_DSN=postgres://signoz:signoz@postgres:5432/signoz
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PostgreSQL for metadata (users, dashboards, alerts). ClickHouse for telemetry (traces, metrics, logs).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Security Warning That Made Me Pause
&lt;/h2&gt;

&lt;p&gt;I almost missed this. About 30 seconds into the signoz logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CRITICAL SECURITY ISSUE: No JWT secret key specified!
Your user sessions are vulnerable to tampering and unauthorized access.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe2kn0fol4swti78l46h0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe2kn0fol4swti78l46h0.png" alt="SigNoz JWT Security Warning in docker logs" width="800" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foundry does not generate a JWT secret. Your deployment runs with unsigned tokens by default. I checked the env vars. Nothing. Checked &lt;code&gt;casting.yaml.lock&lt;/code&gt;. Nothing. It's just not there.&lt;/p&gt;

&lt;p&gt;The fix:&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;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;signoz&lt;/span&gt;&lt;span class="pi"&gt;:&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;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;SIGNOZ_TOKENIZER_JWT_SECRET&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;put-a-64-char-random-string-here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add that to your &lt;code&gt;casting.yaml&lt;/code&gt; and re-deploy. Without it, anyone who sees a session token can forge one. There's a GitHub issue open for this at &lt;a href="https://github.com/SigNoz/signoz/issues/8400" rel="noopener noreferrer"&gt;#8400&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ingester Is the Interesting One
&lt;/h2&gt;

&lt;p&gt;The ingester is an OpenTelemetry Collector. It receives traces (OTLP on ports 4317/4318) and writes them to ClickHouse.&lt;/p&gt;

&lt;p&gt;I read the full config. Four pipelines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;traces:   OTLP → span-metrics → batch → ClickHouse
metrics:  OTLP → batch → ClickHouse
logs:     OTLP → batch → ClickHouse
meter:    internal → batch → ClickHouse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trace pipeline is the interesting one. Every incoming span gets turned into latency histogram metrics before it's stored. Those histograms have 17 buckets, from 100 microseconds to 60 seconds.&lt;/p&gt;

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

&lt;p&gt;The batch size surprised me:&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;batch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;send_batch_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50000&lt;/span&gt;
  &lt;span class="na"&gt;send_batch_max_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;55000&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;5s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;50,000 spans per batch. Every 5 seconds. And there's no retry queue at all. The config explicitly disables it:&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;sending_queue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If ClickHouse is slow or goes down, the ingester drops data immediately. I confirmed this across all four exporters. It's intentional. The trade-off is lower latency at the cost of some data loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OpAMP Thing
&lt;/h2&gt;

&lt;p&gt;The ingester also connects to the signoz container via WebSocket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ws://signoz-signoz-0:4320/v1/opamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the Open Agent Management Protocol. The ingester sends status updates every 30 seconds and receives config changes. But before you register a user, there's no organization in the database. So every 30 seconds, this shows up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR  cannot create agent without orgId
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I checked the &lt;code&gt;organizations&lt;/code&gt; table in PostgreSQL. Empty. Of course. The fix is simple: register your admin user, then restart the ingester:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker restart signoz-ingester-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, the errors stop. Well, most of them. There's still a SQL bug in the "delete old agents" query that shows up sometimes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inside ClickHouse
&lt;/h2&gt;

&lt;p&gt;The trace data lives in &lt;code&gt;signoz_traces.signoz_index_v3&lt;/code&gt;. I queried it to make sure my test spans made it through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;serviceName&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;signoz_traces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signoz_index_v3&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;serviceName&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;9   otel-test
18  ai-learning-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They were there. This is the table with 80+ columns. The key design choice: attributes are stored as Map columns, not individual columns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;attributes_string&lt;/span&gt;  &lt;span class="k"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LowCardinality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;attributes_number&lt;/span&gt;  &lt;span class="k"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LowCardinality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;attributes_bool&lt;/span&gt;    &lt;span class="k"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LowCardinality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can set any key-value pair on a span and it goes into the map automatically. No schema changes needed. My Flask app sets &lt;code&gt;student.name&lt;/code&gt; and &lt;code&gt;recommendations.count&lt;/code&gt; — they all appear in the map.&lt;/p&gt;

&lt;p&gt;You can query these span attributes from ClickHouse directly too. The keys live inside the map, so you access them like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;attributes_string&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'student.name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;student_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;attributes_number&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'recommendations.count'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;rec_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_spans&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;signoz_traces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signoz_index_v3&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'student.name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;student_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rec_count&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_spans&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;There are 8 materialized views that pre-compute the service dependency graphs, trace summaries, and latency distributions. One of them does a self-join on the trace table to find parent-child span relationships across different services. That's how the service map is built.&lt;/p&gt;

&lt;p&gt;The table uses a ReplicatedMergeTree engine even with a single node. Partitioned by day. 15-day TTL. 20+ skip indices for fast lookups.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Looks Like in SigNoz
&lt;/h2&gt;

&lt;p&gt;All this data becomes useful when you open the SigNoz UI at &lt;code&gt;http://localhost:8080&lt;/code&gt;. Log in with your admin account, and you can see your traces as flamegraphs, build dashboards with latency metrics, set up alerts when error rates spike, and correlate logs with traces.&lt;/p&gt;

&lt;p&gt;My Flask app's traces showed up in the Trace Explorer right after I sent the first request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukglkg1wvnd8v8g3s7wh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukglkg1wvnd8v8g3s7wh.png" alt="SigNoz Trace Explorer showing application traces" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three traces, each one a student recommendation request. I clicked into one to see the flamegraph:&lt;/p&gt;

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

&lt;p&gt;The trace had four spans: the HTTP request, the Flask route handler, the LLM call, and the database lookup. The total duration was 2.1 seconds. The LLM call alone took 1.8 seconds. The database lookup was 50 milliseconds.&lt;/p&gt;

&lt;p&gt;That tells me where to optimize. If I want to make this app faster, I look at the LLM provider, not the database. Without the trace, I would have guessed they were equally slow. This is the kind of thing I mentioned earlier about the &lt;strong&gt;attributes Map columns in ClickHouse&lt;/strong&gt; — every &lt;code&gt;student.name&lt;/code&gt; and &lt;code&gt;recommendations.count&lt;/code&gt; attribute I set on the span ended up in &lt;code&gt;attributes_string&lt;/code&gt; and &lt;code&gt;attributes_number&lt;/code&gt; automatically, no schema migration needed.&lt;/p&gt;

&lt;p&gt;The Query Builder also lets you filter by any attribute. I set up a simple dashboard showing requests by student grade level. Took about 30 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inside PostgreSQL
&lt;/h2&gt;

&lt;p&gt;52 tables. I listed them all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users, organizations, auth_token, auth_domain, factor_password,
dashboard, dashboard_view, alertmanager_config, alerts, rules,
service_account, pipelines, ttl_setting, span_mapper, ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;users&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id, display_name, email, org_id, updated_at, created_at, is_root, status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One user in my deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;019f5f5c-2611-7683-8ae5-99e83df8c05b  admin@signoz.ai  2026-07-14
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The &lt;code&gt;auth_token&lt;/code&gt; table stores session tokens with a rotation mechanism using &lt;code&gt;access_token&lt;/code&gt;, &lt;code&gt;refresh_token&lt;/code&gt;, and &lt;code&gt;prev_access_token&lt;/code&gt;/&lt;code&gt;prev_refresh_token&lt;/code&gt; columns. When you issue a new token, the old one moves to &lt;code&gt;prev_*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;service_account&lt;/code&gt; table was empty. That's the table for API keys. You create service accounts through the UI, but I couldn't get past the login page programmatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The API Wall
&lt;/h2&gt;

&lt;p&gt;I tried to call the SigNoz API directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/api/v1/login &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"email":"admin@signoz.ai","password":"Admin@123Signoz!"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returned the HTML page. The entire SPA. Not a JSON token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9siub820jkux5vwsjs5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9siub820jkux5vwsjs5z.png" alt="cURL login request returning HTML" width="797" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The browser version works fine though. Open &lt;code&gt;http://localhost:8080&lt;/code&gt;, enter your credentials, and the SigNoz dashboard loads.&lt;/p&gt;

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

&lt;p&gt;Turns out SigNoz uses session-based auth for the browser. The login endpoint returns session cookies for the SPA, not a JSON token. The logs told the same story:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/v1/user → 401 unauthenticated
/api/v2/sessions/rotate → 400 refresh token required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I was stuck. The &lt;code&gt;service_account&lt;/code&gt; table in PostgreSQL was sitting there ready — that's where API keys live. But I couldn't create one through the API because I couldn't log in through the API. Circular problem.&lt;/p&gt;

&lt;p&gt;The way around it: log into the UI, go to &lt;strong&gt;Settings &amp;gt; Service Accounts&lt;/strong&gt;, create a token, and use it as a header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/api/v1/dashboards &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"signoz-access-token: &amp;lt;your-service-account-token&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No session cookie needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Tell My Past Self
&lt;/h2&gt;

&lt;p&gt;If I were doing this again, here's what I'd do differently:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Read &lt;code&gt;casting.yaml.lock&lt;/code&gt; on day one. It has everything: configs, env vars, IPs. Find it in your project directory and read it before touching anything else.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the JWT secret before registering users. Add &lt;code&gt;SIGNOZ_TOKENIZER_JWT_SECRET&lt;/code&gt; to your casting.yaml. Do it now, not after you have users in the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wait 30 seconds after &lt;code&gt;foundryctl cast&lt;/code&gt;. The containers need time to settle. The startup errors look scary but they're normal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the ingester after registration. The OpAMP errors go away.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Query ClickHouse directly when the UI blocks you. &lt;code&gt;docker exec ... clickhouse-client&lt;/code&gt; works without any authentication. All the data is there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the lock file as your source of truth. The ingester config, the ClickHouse config, the PostgreSQL config. It's all in &lt;code&gt;casting.yaml.lock&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ds7d0qev288qgi6ncif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ds7d0qev288qgi6ncif.png" alt="Architecture diagram showing Docker containers and data flow" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Six containers, two databases, and a missing JWT secret. Not bad for one YAML file. If you try Foundry yourself, read the lock file on day one, not day two like I did.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This was my entry for the Agents of SigNoz pre-event blog contest. Foundry is SigNoz's one-command deployment tool — the casting.yaml and lock file are in the repo if you want to try it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>signoz</category>
      <category>opentelemetry</category>
      <category>observability</category>
      <category>docker</category>
    </item>
    <item>
      <title>AI Is Making Students Worse at Learning — Here's Why That Matters</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Tue, 07 Jul 2026 17:44:04 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/ai-is-making-students-worse-at-learning-heres-why-that-matters-32fg</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/ai-is-making-students-worse-at-learning-heres-why-that-matters-32fg</guid>
      <description>&lt;h1&gt;
  
  
  AI Is Making Students Worse at Learning — Here's Why That Matters
&lt;/h1&gt;

&lt;p&gt;I want to say something uncomfortable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI is making it harder for students to learn.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not in the obvious way — not because the tools are confusing or broken. But because they work &lt;em&gt;too well&lt;/em&gt;. Every time a student gets stuck, they open ChatGPT, paste the error, get the fix, and move on. The problem is solved. The learning didn't happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: The Struggle Was the Point
&lt;/h2&gt;

&lt;p&gt;When I was learning to code, getting stuck was the curriculum. You would stare at a bug for two hours, try six different things, fail at all of them, and then — maybe — find the answer. That two hours of failure was where the actual learning lived. You built mental models. You learned &lt;em&gt;why&lt;/em&gt; things break. You remembered.&lt;/p&gt;

&lt;p&gt;AI removes that entire process. The student goes from stuck → solved in 10 seconds. The code works. But ask them the next day why the fix worked, and they cannot tell you.&lt;/p&gt;

&lt;p&gt;What we are seeing is not accelerated learning. It is &lt;strong&gt;answer acquisition&lt;/strong&gt;. And those are not the same thing.&lt;/p&gt;

&lt;p&gt;Cognitive science has known for decades that the "testing effect" — struggling to retrieve information from memory — is what builds long-term retention. AI bypasses that retrieval step entirely. The student gets the answer, feels productive, and learns nothing durable. Speed without retention is just busy work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Historical Pattern We Are Ignoring
&lt;/h2&gt;

&lt;p&gt;This is not the first time technology has been sold to us as a productivity tool while quietly making us worse at something important.&lt;/p&gt;

&lt;p&gt;In the late 2000s, social media platforms were marketed exactly the same way AI is marketed today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"Connect with colleagues and share ideas professionally."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"A powerful networking tool for your career."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Stay updated with industry thought leaders."&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fast forward fifteen years and every phone ships with a "Screen Time" or "Digital Wellbeing" feature designed to limit the exact apps that were supposed to make us productive. We had to build cages for the tools we invited into our lives.&lt;/p&gt;

&lt;p&gt;AI is following the same trajectory. Right now, every company is marketing their AI assistant as a productivity multiplier. But for students — for learners — that framing is wrong.&lt;/p&gt;

&lt;p&gt;When you give a student an AI that writes their code, their essays, and their problem solutions, you are not making them productive. You are making them dependent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Environmental Cost Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;There is another layer to this that gets overlooked. Every AI query consumes energy and water for data center cooling. Estimates vary widely — older analyses put ChatGPT at 5-10x the energy of a Google search, while newer model optimizations have narrowed that gap significantly. But even on the conservative end, a student asking AI what they could look up in documentation is still a net increase in compute waste.&lt;/p&gt;

&lt;p&gt;Most student queries — "what does this error mean," "explain this concept," "write a function that does X" — could be answered by a web search, a documentation page, or a textbook. The AI is not unlocking new knowledge. It is replacing the act of looking something up. And that trade-off is rarely worth the environmental cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should Governments Have Done?
&lt;/h2&gt;

&lt;p&gt;I believe governments should have stepped in much earlier on AI regulation — not to stop innovation, but to control distribution, especially in education. We did not wait fifteen years to regulate social media's impact on teenagers. But with AI, we are repeating the same mistake. The horse is already out of the barn.&lt;/p&gt;

&lt;p&gt;Some countries are starting to act. Italy temporarily banned ChatGPT in 2023 over privacy concerns. The EU AI Act is trying to create a regulatory framework. But these efforts are reactive and slow. The damage to how a generation approaches learning is already happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Students Can Do Now
&lt;/h2&gt;

&lt;p&gt;Since regulation is not coming fast enough, the responsibility falls on individual students. And I know that is an unfair burden to place on someone who is just trying to get through school. But here is what I would recommend:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Treat AI like social media, not a calculator
&lt;/h3&gt;

&lt;p&gt;Put ChatGPT and Copilot in the same category as Instagram and TikTok — tools that can consume your time and replace your thinking. Use your phone's app limits if you have to. Block these tools during study hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Implement a "try-first" rule
&lt;/h3&gt;

&lt;p&gt;Before you ask AI for help, spend at least 15-20 minutes trying to solve the problem yourself. Search the web. Read documentation. Try a wrong approach and see why it fails. Only after that should you bring in the AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use AI as a tutor, not a solution generator
&lt;/h3&gt;

&lt;p&gt;Instead of "write a function that sorts this array," try "explain the different sorting algorithms and when each one is appropriate." One gives you answers. The other helps you understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Be honest with yourself about what you actually know
&lt;/h3&gt;

&lt;p&gt;At the end of the week, ask yourself: can I explain the concepts I "learned" without AI assistance? If the answer is no, you did not learn them. You just collected answers.&lt;/p&gt;

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

&lt;p&gt;AI is an incredible technology. It has genuine use cases in research, healthcare, accessibility, and automation of genuinely tedious work. But not everything that is powerful needs to be everywhere.&lt;/p&gt;

&lt;p&gt;For students, the most valuable skill is not the ability to get the right answer quickly. It is the ability to solve problems they have never seen before, with tools they understand deeply. AI shortcuts that process at exactly the wrong moment — when the foundation is being built.&lt;/p&gt;

&lt;p&gt;We need to stop pretending that giving every student an AI assistant is an unqualified good. The tools are here to stay. But how we use them — and how we teach students to use them — will determine whether this generation of learners emerges stronger or more dependent.&lt;/p&gt;

&lt;p&gt;The choice is ours. But we need to start talking about it honestly.&lt;/p&gt;

</description>
      <category>education</category>
      <category>ai</category>
      <category>students</category>
      <category>learning</category>
    </item>
    <item>
      <title>The Reflex Loop: A Guide to Building Self-Healing Agentic Infrastructure</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Mon, 27 Apr 2026 06:38:58 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/the-reflex-loop-a-guide-to-building-self-healing-agentic-infrastructure-3flh</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/the-reflex-loop-a-guide-to-building-self-healing-agentic-infrastructure-3flh</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Building the Immune System: How to Create Self-Healing AI Agents
&lt;/h1&gt;

&lt;p&gt;While most of the AI world is focused on chatbots, I’ve been obsessed with &lt;strong&gt;Resilience&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We want our agents to be proactive—running in the background, monitoring our lives, and getting things done. But what happens when the code rots? What happens when a service changes its API schema while you're asleep? &lt;/p&gt;

&lt;p&gt;In this post, I break down the architecture of &lt;strong&gt;ClawReflex&lt;/strong&gt;, a tutorial on how to build a self-healing layer for the OpenClaw framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Reflex Loop" Architecture
&lt;/h2&gt;

&lt;p&gt;To build an agent that can fix itself, you need a four-step loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Detection:&lt;/strong&gt; Constantly tailing logs for specific failure patterns (Regex is your friend here).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnosis:&lt;/strong&gt; Passing the &lt;em&gt;stack trace&lt;/em&gt; AND the &lt;em&gt;source code&lt;/em&gt; to an LLM. An error message alone isn't enough; the AI needs the context of the file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surgery:&lt;/strong&gt; Using a "Surgeon Agent" to apply a precise patch. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification:&lt;/strong&gt; Running a dry-run of the module before it goes back into production.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why "Local-First" Matters for Resilience
&lt;/h2&gt;

&lt;p&gt;By using OpenClaw and local LLMs (via Groq or Ollama), your "Immune System" stays private. Your code never leaves your machine, and your guardian works even if the cloud is down.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Secret Sauce: Emotional Resonance
&lt;/h2&gt;

&lt;p&gt;One of my key takeaways from this project was that &lt;strong&gt;Resilience isn't just about code; it's about the developer's state of mind.&lt;/strong&gt; By having the agent generate a "Peace of Mind" report after a fix, we move the AI from being a "tool" to being a "reliable partner."&lt;/p&gt;

&lt;h2&gt;
  
  
  ClawCon Michigan
&lt;/h2&gt;

&lt;p&gt;I'd love to share these findings with the folks at ClawCon Michigan! The future of AI isn't just "smarter" agents, but "sturdier" ones.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>ClawReflex: Building a Self-Healing Immune System for Autonomous Agents</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Mon, 27 Apr 2026 06:37:41 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/clawreflex-building-a-self-healing-immune-system-for-autonomous-agents-1dne</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/clawreflex-building-a-self-healing-immune-system-for-autonomous-agents-1dne</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;ClawReflex&lt;/strong&gt;, an autonomous "Immune System" for the OpenClaw ecosystem. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; AI agents are inherently fragile. If an external API changes, or a background service goes down, your proactive agent goes silent. Usually, this means the developer has to wake up at 2 AM to fix a broken URL or a missing dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution:&lt;/strong&gt; ClawReflex is a background guardian that monitors your OpenClaw gateway logs 24/7. When a skill crashes, it doesn't just report the error—it captures the stack trace, uses AI to diagnose the failure, creates a Git safety backup, and &lt;strong&gt;autonomously rewrites the broken code&lt;/strong&gt; to restore functionality instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used OpenClaw
&lt;/h2&gt;

&lt;p&gt;ClawReflex is designed as a meta-layer for OpenClaw:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event-Driven Monitoring:&lt;/strong&gt; Uses Node.js &lt;code&gt;fs.watchFile&lt;/code&gt; to monitor the OpenClaw &lt;code&gt;gateway.log&lt;/code&gt; for &lt;code&gt;[CRITICAL_FAILURE]&lt;/code&gt; patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic Reasoning (SOUL.md/AGENTS.md):&lt;/strong&gt; I defined a "Guardian Architect" persona that prioritizes system stability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Powered Surgery:&lt;/strong&gt; Leverages the Groq Llama-3 API to perform live code repair on the &lt;code&gt;AgentSkills/&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety Infrastructure:&lt;/strong&gt; Integrates Git-based rollbacks so that every "healing" action is non-destructive and fully reversible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/iaSwAptGMcU" rel="noopener noreferrer"&gt;https://youtu.be/iaSwAptGMcU&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo showcases a complete "Healing Loop":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;WeatherSkill&lt;/strong&gt; fails because it relies on a decommissioned 2025 API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ClawReflex&lt;/strong&gt; detects the &lt;code&gt;ENOTFOUND&lt;/code&gt; error and triggers the "Surgeon."&lt;/li&gt;
&lt;li&gt;The AI analyzes the code, finds a modern alternative (&lt;code&gt;wttr.in&lt;/code&gt;), and &lt;strong&gt;patches the skill live&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The system generates a &lt;strong&gt;"Peace of Mind"&lt;/strong&gt; report—an emotional touchpoint that reassures the developer that the system is safe.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/agp-369/clawreflex" rel="noopener noreferrer"&gt;https://github.com/agp-369/clawreflex&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI as a Maintenance Tool:&lt;/strong&gt; We often use AI to write &lt;em&gt;new&lt;/em&gt; code, but its true power lies in maintaining &lt;em&gt;existing&lt;/em&gt; code. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Emotional Gap:&lt;/strong&gt; I learned that developers don't just need error logs; they need to know their system is looking out for them. Adding "Emotional Resonance" to a technical tool completely changes the user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety is Paramount:&lt;/strong&gt; Autonomous code modification is scary. Building the Git-rollback layer was the most challenging and important part of the project to ensure trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ClawCon Michigan
&lt;/h2&gt;

&lt;p&gt;This project was built with the spirit of ClawCon in mind—pushing the boundaries of what local, private, and autonomous AI can do for the everyday developer. I'd love to see the community's reaction to self-healing infrastructure!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why I spent my weekend building a "Cyber-Immune System" for students</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Sun, 01 Mar 2026 10:52:31 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/why-i-spent-my-weekend-building-a-cyber-immune-system-for-students-4682</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/why-i-spent-my-weekend-building-a-cyber-immune-system-for-students-4682</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;StudentGuard Syndicate&lt;/strong&gt; for the global student community—the interns, freshers, and career-starters who are currently being hunted by a multi-million dollar recruitment fraud industry. &lt;/p&gt;

&lt;p&gt;This isn't an imaginary problem. It started when my roommate got a LinkedIn message for a "Global Amazon Internship." He spent three days in a fake Telegram interview, feeling on top of the world. Then they sent a fake $1,200 "equipment check" and asked him to buy a specific MacBook. He paid. Then... silence. The recruiter vanished. His bank account was drained. &lt;/p&gt;

&lt;p&gt;Rec scammers weaponize automation to scale their malice, but students usually suffer in isolation. I realized that &lt;strong&gt;silence is the scammer's best friend.&lt;/strong&gt; I built this to turn our individual experiences into a collective weapon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;StudentGuard Syndicate&lt;/strong&gt; is an immersive, sovereign community defense network. It moves beyond "AI guessing" by using real-time cybersecurity forensics to build a decentralized immune system. &lt;/p&gt;

&lt;p&gt;The platform interrogates job lead artifacts, metadata headers, and global RDAP registries to provide cryptographic proof of truth. One student's scan doesn't just protect them—it strengthens the global ledger via Supabase, warning thousands of others in the Syndicate instantly. Every member receives a "Sovereign Passport" to track their contributions to the collective safety of their peers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live Platform:&lt;/strong&gt; &lt;a href="https://student-guard-syndicate.vercel.app" rel="noopener noreferrer"&gt;https://student-guard-syndicate.vercel.app&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Video Dispatch:&lt;/strong&gt; [&lt;a href="https://youtu.be/TJ3JwWz4CnU" rel="noopener noreferrer"&gt;https://youtu.be/TJ3JwWz4CnU&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/agp-369" rel="noopener noreferrer"&gt;
        agp-369
      &lt;/a&gt; / &lt;a href="https://github.com/agp-369/student-guard-syndicate" rel="noopener noreferrer"&gt;
        student-guard-syndicate
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🛡️ Sovereign community defense network against recruitment fraud. Powered by Gemini 2.5 Flash, Supabase Real-time, and Clerk.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🛡️ StudentGuard Syndicate&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;&lt;em&gt;Engineering Global Immunity for the Next Generation of Careers.&lt;/em&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://student-guard-syndicate.vercel.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fddd9e25efe860acba84e153f5f9f1a4ea625023a6f174c1ef54d96bca53340a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f536f7665726569676e74795f4e6f64652d4163746976652d656d6572616c642e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d736869656c64" alt="Sovereignty Node: Active"&gt;&lt;/a&gt;
&lt;a href="https://ai.google.dev" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7214090b35e53164b619424331874d919a296d1f15faa1b49ead283ee1158c5a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f496e74656c6c6967656e63652d47656d696e695f322e355f466c6173682d696e6469676f2e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d676f6f676c652d67656d696e69" alt="Intelligence: Gemini 2.5 Flash"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;StudentGuard Syndicate is a high-fidelity, sovereign community defense network designed to weaponize collective intelligence against recruitment fraud. Unlike traditional scanners, the Syndicate uses multi-layer forensics—extracting hidden metadata and pinging global DNS registries—to build a decentralized immune system for students entering the workforce.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🏛️ Core Architectural Protocols&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Forensic DNA Probing&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The engine doesn't just read text; it interrogates it. Our backend actively extracts URL entities and pings global &lt;strong&gt;RDAP/WHOIS&lt;/strong&gt; registries to identify the registration age of target domains.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Heuristic:&lt;/em&gt; Any domain under 180 days old claiming to be a major corporation triggers a &lt;strong&gt;Critical Threat Alert&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Sovereign PDF Node (Privacy-First)&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Career documents contain highly sensitive personal data. Upholding our &lt;strong&gt;Sovereign Mandate&lt;/strong&gt;, we leverage &lt;strong&gt;WebAssembly (pdfjs-dist)&lt;/strong&gt; to parse PDF offer letters entirely within the user's browser RAM. No sensitive data ever touches our servers.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. Synchronized&lt;/h3&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/agp-369/student-guard-syndicate" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;To build a professional-grade security authority, I integrated a high-end, real-time tech stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Sovereign Identity (Clerk):&lt;/strong&gt; I integrated &lt;strong&gt;Clerk&lt;/strong&gt; to manage secure, passwordless authentication. This ensures every Syndicate member has a unique, verifiable identity while maintaining their privacy.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Intelligence Node (Gemini 2.5 Flash):&lt;/strong&gt; Powered by the latest &lt;strong&gt;Gemini 2.5 Flash&lt;/strong&gt; core. It performs deep behavioral heuristics to identify "off-platform redirection" patterns common in Telegram and WhatsApp scams.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Global Ledger (Supabase):&lt;/strong&gt; Built with &lt;strong&gt;Supabase&lt;/strong&gt;. Every forensic scan is synchronized in real-time across the network using PostgreSQL listeners, turning individual data into community immunity.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Privacy Sovereignty (WASM):&lt;/strong&gt; We use &lt;strong&gt;pdfjs-dist (WebAssembly)&lt;/strong&gt; to parse sensitive PDFs entirely in the browser RAM. Upholding our privacy mandate, no sensitive offer letters ever touch our servers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Forensic Probing:&lt;/strong&gt; Custom API nodes perform active &lt;strong&gt;RDAP/WHOIS&lt;/strong&gt; pings to verify the registration age of company domains.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔮 The Future Protocol
&lt;/h3&gt;

&lt;p&gt;The Syndicate roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Browser Sentinel:&lt;/strong&gt; A Chrome extension to bring Syndicate forensics directly into Gmail and LinkedIn.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Verified Recruiter Keys:&lt;/strong&gt; Official HR departments can cryptographically sign their offers to bypass Syndicate probes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;University Uplink:&lt;/strong&gt; Direct integration with university placement portals to provide a "Verified Authority" seal on job postings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stay Safe. Stay Sovereign. Join the Syndicate.&lt;/strong&gt; 🥂🛡️🚀✨&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
      <category>studentguard</category>
    </item>
    <item>
      <title>Distributed Database Internals: The Engineering Behind Log-Structured Merge (LSM) Trees</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Thu, 19 Feb 2026 19:48:36 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/distributed-database-internals-the-engineering-behind-log-structured-merge-lsm-trees-2258</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/distributed-database-internals-the-engineering-behind-log-structured-merge-lsm-trees-2258</guid>
      <description>&lt;p&gt;In the world of high-performance distributed databases like &lt;strong&gt;Cassandra&lt;/strong&gt;, &lt;strong&gt;ScyllaDB&lt;/strong&gt;, and &lt;strong&gt;RocksDB&lt;/strong&gt;, the traditional B-Tree architecture often hits a wall. While B-Trees are excellent for read-heavy workloads, they struggle with high-velocity write traffic due to random I/O and page fragmentation.&lt;/p&gt;

&lt;p&gt;The industry's answer to this 'write problem' is the &lt;strong&gt;Log-Structured Merge (LSM) Tree&lt;/strong&gt;. This architecture transforms random writes into sequential writes, allowing databases to ingest millions of records per second with minimal latency. In this deep-dive, we will explore the internals of how LSM trees work, why they are so fast, and the trade-offs they make.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Write Path: Sequential is King
&lt;/h2&gt;

&lt;p&gt;The fundamental principle of an LSM tree is that appending to a log is always faster than updating a page in a B-Tree. Instead of modifying data in place, an LSM tree treats every write as an 'upsert'—it simply appends the new data to a log.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Three Core Components
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write-Ahead Log (WAL):&lt;/strong&gt; A persistent append-only log on disk. If the server crashes, the WAL is used to reconstruct the in-memory data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MemTable:&lt;/strong&gt; An in-memory data structure (typically a SkipList or a Balanced Tree) that stores incoming writes in sorted order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sorted String Tables (SSTables):&lt;/strong&gt; Once the MemTable reaches a certain size, it is 'flushed' to disk as an immutable, sorted file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxLL0osyFDwCbLmUlBQUAgvyixJjQaTCkGphaWpxSWxCrq6dgrhjj4QYV3HjNTEFAWf_PRYJC1gNb6pudG-qbkhiUk5qQq6Cp55ur6puflFlVCFvqm5IGU1bjmlxRkK5RmpeQpupTk5NQrBwSHRwcEwbf55ui6Zxdmx1gCBkDAW" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxLL0osyFDwCbLmUlBQUAgvyixJjQaTCkGphaWpxSWxCrq6dgrhjj4QYV3HjNTEFAWf_PRYJC1gNb6pudG-qbkhiUk5qQq6Cp55ur6puflFlVCFvqm5IGU1bjmlxRkK5RmpeQpupTk5NQrBwSHRwcEwbf55ui6Zxdmx1gCBkDAW" alt="LSM Write Path" width="805" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Deep Dive: MemTable Flushes and SSTable Immutability
&lt;/h2&gt;

&lt;p&gt;When the MemTable is full, the database starts a background thread to write its contents to disk. Because the MemTable is already sorted in memory, the resulting &lt;strong&gt;SSTable&lt;/strong&gt; is written sequentially. This is a critical performance win: sequential disk I/O is orders of magnitude faster than random I/O, even on modern NVMe drives.&lt;/p&gt;

&lt;p&gt;Once an SSTable is written, it is &lt;strong&gt;immutable&lt;/strong&gt;. It is never changed. If a user updates a key, a new version of that key is written to a new SSTable. This eliminates the need for complex locking mechanisms and page splits found in B-Trees.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Challenge: Read Amplification and Compaction
&lt;/h2&gt;

&lt;p&gt;If data is spread across dozens of immutable SSTables, how do we find a specific key? We have to check the MemTable first, and then check every SSTable from newest to oldest. This is called &lt;strong&gt;Read Amplification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To solve this, LSM trees use a process called &lt;strong&gt;Compaction&lt;/strong&gt;. Compaction merges multiple SSTables into a single, larger SSTable, discarding old versions of keys and deleted records (tombstones).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxly7EKgCAUBdC9r7g_EKRr0FLjq8W2aLB4WFApJk1-fCBCQ_s5xmu3YezqAgComogfPlBBqVEvB98zyrKJPXvDUNaHCBIZiQ_lLhJu7en0GnZ7RZDMWP6wTLhjdlDBem04gobMh7l-AVTNL40%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxly7EKgCAUBdC9r7g_EKRr0FLjq8W2aLB4WFApJk1-fCBCQ_s5xmu3YezqAgComogfPlBBqVEvB98zyrKJPXvDUNaHCBIZiQ_lLhJu7en0GnZ7RZDMWP6wTLhjdlDBem04gobMh7l-AVTNL40%3D" alt="LSM Compaction Strategy" width="194" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Leveled vs. Size-Tiered Compaction
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Size-Tiered Compaction Strategy (STCS):&lt;/strong&gt; Good for write-heavy workloads (Cassandra default). It groups SSTables of similar sizes together and merges them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leveled Compaction Strategy (LCS):&lt;/strong&gt; Good for read-heavy workloads (RocksDB/ScyllaDB). It organizes SSTables into hierarchical levels, ensuring that each level contains non-overlapping keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Engineering Implementation: A Simple MemTable in Python
&lt;/h2&gt;

&lt;p&gt;To understand the logic, let's look at a simplified implementation of a MemTable using a Python dictionary (acting as our sorted map) and a simulated flush trigger.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LSMStore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memtable_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable_limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memtable_limit&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sstables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# List of filenames
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# 1. In a real DB, we'd write to WAL first
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;

        &lt;span class="c1"&gt;# 2. Check if we need to flush
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable_limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flush_to_sstable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;flush_to_sstable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sstable_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.db&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="c1"&gt;# Sort the memtable and write to 'disk'
&lt;/span&gt;        &lt;span class="n"&gt;sorted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[*] Flushing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sorted_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; keys to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Clear MemTable for new writes
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sstables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Check MemTable first
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memtable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c1"&gt;# Check SSTables from newest to oldest (simulated)
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sstable&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sstables&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="c1"&gt;# In a real DB, we use Bloom Filters here to skip files
&lt;/span&gt;            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Performance Comparison: LSM vs. B-Tree
&lt;/h2&gt;

&lt;p&gt;When choosing a storage engine, the decision usually boils down to the &lt;strong&gt;RUM Conjecture&lt;/strong&gt; (Read, Update, Memory overhead).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;B-Tree (PostgreSQL/MySQL)&lt;/th&gt;
&lt;th&gt;LSM Tree (RocksDB/Cassandra)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write Throughput&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lower (Random I/O)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Ultra-High (Sequential I/O)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Read Throughput&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Very High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate (Read Amplification)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Space Efficiency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lower (Page Fragmentation)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High (Compressed SSTables)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write Amplification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;High (due to Compaction)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  6. Real-World Applications
&lt;/h2&gt;

&lt;p&gt;LSM trees are the engine behind the world's most scalable data platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache Cassandra:&lt;/strong&gt; Uses LSM trees to provide high availability and write performance for massive datasets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RocksDB:&lt;/strong&gt; Facebook's high-performance embeddable key-value store, which many other databases (like CockroachDB and TiDB) use as their underlying storage engine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ScyllaDB:&lt;/strong&gt; A C++ rewrite of Cassandra that uses advanced Leveled Compaction to minimize tail latency.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The Log-Structured Merge Tree is a masterpiece of systems engineering. By accepting the cost of background compaction, it unlocks a level of write performance that B-Trees simply cannot match. If your application needs to ingest telemetry data, logs, or real-time event streams at scale, understanding the LSM tree is not just useful—it's essential.&lt;/p&gt;

</description>
      <category>database</category>
      <category>distributedsystems</category>
      <category>storage</category>
      <category>performance</category>
    </item>
    <item>
      <title>WebAssembly (Wasm) at the Edge: Why the Future of Serverless is not Docker</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Thu, 19 Feb 2026 19:44:46 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/webassembly-wasm-at-the-edge-why-the-future-of-serverless-is-not-docker-5368</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/webassembly-wasm-at-the-edge-why-the-future-of-serverless-is-not-docker-5368</guid>
      <description>&lt;p&gt;For the last decade, Docker and containers have defined how we deploy software. But as we move toward the 'Edge', the limitations of containers—slow cold starts, heavy memory footprints, and complex security isolation—are becoming visible.&lt;/p&gt;

&lt;p&gt;The answer to these challenges isn't 'smaller containers'. It is &lt;strong&gt;WebAssembly (Wasm)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is WebAssembly?
&lt;/h2&gt;

&lt;p&gt;Originally designed for the browser, Wasm is a binary instruction format for a stack-based virtual machine. It's portable, secure, and runs at near-native speed. In the serverless world, it allows us to run 'nanoprocesses' that start in microseconds, not seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: Wasm at the Edge
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJw1jrEKwjAURXe_4v5ABudKB7WbOETFIXQIzSMGTNPmJeCQj5ekuhzevZwLz0a9vHA_dzsAeDBFVQFJayZOI4ToMRhLqgLXYGjc3JaF6MspvA1uSceEA_aeC56avaqAzHNy_j9pVZ0MH5pyooJLsG5Sx8xuJuYt_uR2N1sSL2FmKu2_7gvJ-TmO" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJw1jrEKwjAURXe_4v5ABudKB7WbOETFIXQIzSMGTNPmJeCQj5ekuhzevZwLz0a9vHA_dzsAeDBFVQFJayZOI4ToMRhLqgLXYGjc3JaF6MspvA1uSceEA_aeC56avaqAzHNy_j9pVZ0MH5pyooJLsG5Sx8xuJuYt_uR2N1sSL2FmKu2_7gvJ-TmO" alt="Wasm Edge Workflow" width="254" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Wasm Wins in Serverless
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instant Cold Starts:&lt;/strong&gt; Containers take seconds to boot. Wasm modules start in less than 1 millisecond. This eliminates the 'cold start' problem that plagues AWS Lambda and Google Cloud Functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Density:&lt;/strong&gt; You can run thousands of Wasm modules on a single server where you could only run dozens of containers. This efficiency is why companies like Cloudflare and Fastly are betting their entire edge strategy on Wasm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Wasm uses a strict 'Capabilities-Based' security model. A module has zero access to the system (files, network) unless explicitly granted.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Docker Containers&lt;/th&gt;
&lt;th&gt;WebAssembly (Wasm)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Boot Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~1 - 5 seconds&lt;/td&gt;
&lt;td&gt;&amp;lt; 1 millisecond&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory Usage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High (MBs)&lt;/td&gt;
&lt;td&gt;Ultra-Low (KBs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Isolation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OS-Level (Namespaces)&lt;/td&gt;
&lt;td&gt;VM-Level (Sandboxed)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;WebAssembly isn't replacing Docker for everything, but for high-scale, low-latency edge computing, it is the clear winner. The transition is already happening—are you ready for it?&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>edgecomputing</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Zero Trust in the Kernel: Leveraging eBPF for Deep Observability</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Thu, 19 Feb 2026 19:40:51 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/zero-trust-in-the-kernel-leveraging-ebpf-for-deep-observability-gnk</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/zero-trust-in-the-kernel-leveraging-ebpf-for-deep-observability-gnk</guid>
      <description>&lt;p&gt;The traditional 'castle and moat' security model is dead. In a world of microservices and ephemeral containers, the network perimeter has dissolved. To achieve true &lt;strong&gt;Zero Trust&lt;/strong&gt;, we can no longer rely on external firewalls. We need to move the security logic into the heart of the operating system: the Linux Kernel.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is eBPF?
&lt;/h2&gt;

&lt;p&gt;eBPF (Extended Berkeley Packet Filter) is a revolutionary technology that allows us to run sandboxed programs inside the Linux kernel without changing the kernel source code or loading a module. It provides a direct, low-overhead hook into every system call and network packet passing through your server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zero Trust Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxVzEEKgkAUBuB9p_gvIB1ACNSyRRJDthtcDPZS8enIc8Sk6e6Btmn_8VVihhrZLdwBQKSjYYCyjwJBcPD5MpaG2SPWWdNPL1xIeuJiw_Fq0oYdiUfyplilUGIrMd1nI8lKImY7exz1ldxspUXuTNn-lo3EbMvW46RzKidp3IKISdyfuRNTR45k8Uj1WczT9GavxHbkaprGIvwCcpBBFQ%3D%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxVzEEKgkAUBuB9p_gvIB1ACNSyRRJDthtcDPZS8enIc8Sk6e6Btmn_8VVihhrZLdwBQKSjYYCyjwJBcPD5MpaG2SPWWdNPL1xIeuJiw_Fq0oYdiUfyplilUGIrMd1nI8lKImY7exz1ldxspUXuTNn-lo3EbMvW46RzKidp3IKISdyfuRNTR45k8Uj1WczT9GavxHbkaprGIvwCcpBBFQ%3D%3D" alt="eBPF Security Flow" width="968" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By leveraging eBPF, we can implement &lt;strong&gt;Identity-Aware Networking&lt;/strong&gt;. Instead of filtering traffic based on brittle IP addresses, we filter based on the process ID, the container metadata, and even the specific function call that initiated the connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Security Teams are Pivoting to eBPF
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deep Observability:&lt;/strong&gt; Standard tools see &lt;em&gt;that&lt;/em&gt; a connection happened. eBPF sees &lt;em&gt;who&lt;/em&gt; started it, &lt;em&gt;what&lt;/em&gt; file they read before connecting, and &lt;em&gt;how&lt;/em&gt; many bytes they sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Overhead:&lt;/strong&gt; Unlike sidecar proxies (like Istio), eBPF runs in the kernel space. There is no 'extra hop' for your data, meaning sub-millisecond latency for security checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Security:&lt;/strong&gt; We can detect and block malicious behavior—like a web server suddenly trying to run &lt;code&gt;chmod&lt;/code&gt; on a sensitive file—in real-time, before the command even finishes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementation Blueprint: A Simple Socket Filter
&lt;/h2&gt;

&lt;p&gt;While writing raw eBPF is complex, libraries like &lt;code&gt;cilium/ebpf&lt;/code&gt; (Go) or &lt;code&gt;libbpf-rs&lt;/code&gt; (Rust) make it accessible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Concept: Monitoring outbound connections in Go&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Load the eBPF program into the kernel&lt;/span&gt;
    &lt;span class="n"&gt;objs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bpfObjects&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;loadBpfObjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;objs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;objs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Attach the program to a Kprobe (e.g., tcp_v4_connect)&lt;/span&gt;
    &lt;span class="n"&gt;kp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kprobe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;tcp_v4_connect&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KprobeTcpV4Connect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;attach&lt;/span&gt; &lt;span class="n"&gt;kprobe&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;kp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Monitoring&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="err"&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;h2&gt;
  
  
  Production Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;IPTables (Legacy)&lt;/th&gt;
&lt;th&gt;Sidecar Proxy (Istio)&lt;/th&gt;
&lt;th&gt;eBPF (Cilium)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context Aware&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IP-only&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High (Kernel Level)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Ultra-Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Very High&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;The move toward eBPF is the most significant shift in systems engineering of the last decade. It allows us to build security into the fabric of the platform rather than bolting it on as an afterthought. For any serious Cloud Native journey, eBPF isn't just a tool—it's the foundation.&lt;/p&gt;

</description>
      <category>security</category>
      <category>linux</category>
      <category>ebpf</category>
      <category>devops</category>
    </item>
    <item>
      <title>The Ultimate Guide to Self-Reflective RAG (CRAG): Solving the Hallucination Crisis</title>
      <dc:creator>AGP Marka</dc:creator>
      <pubDate>Thu, 19 Feb 2026 19:33:26 +0000</pubDate>
      <link>https://dev.to/agp_marka_62a62d1cdadad70/the-ultimate-guide-to-self-reflective-rag-crag-solving-the-hallucination-crisis-27hf</link>
      <guid>https://dev.to/agp_marka_62a62d1cdadad70/the-ultimate-guide-to-self-reflective-rag-crag-solving-the-hallucination-crisis-27hf</guid>
      <description>&lt;p&gt;In the first wave of AI applications, 'Basic RAG' (Retrieval-Augmented Generation) was the gold standard. We simply embedded documents, stored them in a vector store like Pinecone or Chroma, and fed them to an LLM. It felt like magic.&lt;/p&gt;

&lt;p&gt;But magic fades when it hits production. In real-world scenarios, retrieval is noisy. A semantic match isn't always a factual match. This is why standard RAG pipelines often hallucinate with high confidence. To solve this, we need &lt;strong&gt;Self-Reflective RAG (CRAG)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem: Semantic Noise
&lt;/h2&gt;

&lt;p&gt;Semantic search finds things that 'sound' similar. If a user asks about 'Apple stock prices' and your database has a recipe for 'Apple Pie', the vector distance might still be close enough to pull that irrelevant data. A standard LLM, forced to use that context, will try to reconcile the two, leading to a catastrophic hallucination.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Architecture Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxVjk9rwkAQxe_9FHM0h-AHEISg1FIKxT-thyWHTXxOFuKuTGZjpfjdZRMr9DK8efN7vGGx54Z2y9kLEdFXB5mYNGkdIdcyozyf0wYqDj3EfKPWILSFlbopx9DzOrDv8cD43aBFb32Ncb-N5KApz-nNcUOL4I_ugASl4AreLJ2g1iQhVl3wj4pn8CNcpsWpchxD7IbYHpXZ2d611-ke1f_PkpGYgtksglf8aNICthrkARXMf_2jsYIfjM-o56gT8-q8banw3QVSZrM7R6tfxg%3D%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkroki.io%2Fmermaid%2Fpng%2FeJxVjk9rwkAQxe_9FHM0h-AHEISg1FIKxT-thyWHTXxOFuKuTGZjpfjdZRMr9DK8efN7vGGx54Z2y9kLEdFXB5mYNGkdIdcyozyf0wYqDj3EfKPWILSFlbopx9DzOrDv8cD43aBFb32Ncb-N5KApz-nNcUOL4I_ugASl4AreLJ2g1iQhVl3wj4pn8CNcpsWpchxD7IbYHpXZ2d611-ke1f_PkpGYgtksglf8aNICthrkARXMf_2jsYIfjM-o56gT8-q8banw3QVSZrM7R6tfxg%3D%3D" alt="CRAG Architecture Diagram" width="307" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CRAG introduces a 'Judge' layer between the search results and the LLM. This judge doesn't generate an answer; it strictly evaluates the relationship between the query and the retrieved documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive: The Cross-Encoder Judge
&lt;/h2&gt;

&lt;p&gt;The most effective way to implement this judge is using a &lt;strong&gt;Cross-Encoder&lt;/strong&gt;. Unlike standard Bi-Encoders (which create separate embeddings), a Cross-Encoder processes the Query and Document &lt;em&gt;together&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This allows the model to capture the nuanced interactions between words in the query and the document, leading to far more accurate relevance scores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation Snippet
&lt;/h3&gt;

&lt;p&gt;We typically use the &lt;code&gt;sentence-transformers&lt;/code&gt; library with a model like &lt;code&gt;cross-encoder/ms-marco-MiniLM-L-6-v2&lt;/code&gt; for high performance and low latency.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RAGJudge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Light and fast model for real-time judgment
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CrossEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cross-encoder/ms-marco-MiniLM-L-6-v2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Scores each doc against the query
&lt;/span&gt;        &lt;span class="n"&gt;pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# We categorize results based on specific thresholds
&lt;/span&gt;        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CORRECT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AMBIGUOUS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;INCORRECT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling the 'Ambiguous' State
&lt;/h2&gt;

&lt;p&gt;This is where CRAG outshines standard RAG. If the judge labels a document as 'Ambiguous', we don't just give up. We trigger a &lt;strong&gt;Knowledge Augmentation&lt;/strong&gt; step. This usually involves an API call to a search engine like Tavily or Serper.&lt;/p&gt;

&lt;p&gt;The system fetches fresh, real-time data to verify or supplement the internal document, ensuring the final answer is grounded in both your private data and public facts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Metrics in Production
&lt;/h2&gt;

&lt;p&gt;In our latest internal benchmarks, moving from Basic RAG to CRAG showed the following improvements:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Basic RAG&lt;/th&gt;
&lt;th&gt;Self-Reflective RAG (CRAG)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fact Accuracy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;68%&lt;/td&gt;
&lt;td&gt;89%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hallucination Rate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;24%&lt;/td&gt;
&lt;td&gt;6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Token Efficiency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium (due to retry loops)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency (P99)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;850ms&lt;/td&gt;
&lt;td&gt;1.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Common Gotchas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Threshold Sensitivity:&lt;/strong&gt; A score of 0.7 on one model might be a 0.5 on another. You must calibrate your thresholds against a 'Golden Dataset'.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latent Cost:&lt;/strong&gt; Every 'Ambiguous' trigger is an extra API call. Monitor your costs if you are using high-frequency web search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt Poisoning:&lt;/strong&gt; Even with a judge, ensure your system prompt tells the LLM to 'ignore any context if the judge labels it incorrect'.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Self-Reflective RAG is the bridge between AI 'toys' and production-grade software. It recognizes that retrieval is imperfect and builds a safety net into the architecture itself. If you are building for enterprise, this isn't just an option—it's the baseline.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>machinelearning</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
