<?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: NaveenKumar Namachivayam ⚡</title>
    <description>The latest articles on DEV Community by NaveenKumar Namachivayam ⚡ (@qainsights).</description>
    <link>https://dev.to/qainsights</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%2F159517%2F43f7f907-501b-44e8-b748-e740fa80c07e.jpg</url>
      <title>DEV Community: NaveenKumar Namachivayam ⚡</title>
      <link>https://dev.to/qainsights</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qainsights"/>
    <language>en</language>
    <item>
      <title>Stop Your AI Coding CLI From Wasting Tokens on "Hi" and "Thanks"</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Wed, 05 Aug 2026 17:23:35 +0000</pubDate>
      <link>https://dev.to/qainsights/stop-your-ai-coding-cli-from-wasting-tokens-on-hi-and-thanks-4f6b</link>
      <guid>https://dev.to/qainsights/stop-your-ai-coding-cli-from-wasting-tokens-on-hi-and-thanks-4f6b</guid>
      <description>&lt;p&gt;In this blog post, we will see how a small Python script called &lt;strong&gt;&lt;a href="https://github.com/QAInsights/pleasantries" rel="noopener noreferrer"&gt;Pleasantries&lt;/a&gt; &lt;/strong&gt;can stop your AI coding CLI from burning a full model call every time you type "hi", "ok", or "thank you". I built this after noticing how often my own prompts to Claude Code and Qwen Code started with a greeting out of pure habit, and how each one quietly cost tokens and time for zero task value.&lt;/p&gt;

&lt;p&gt;Pleasantries is a lightweight Python pre-hook script that intercepts greeting-only prompts before they reach an AI coding CLI model. It uses regex fullmatch logic to block inputs like "hi," "thank you," or "ok" while allowing prompts that contain pleasantry words but carry a real task.&lt;/p&gt;

&lt;p&gt;The tool supports 15 AI coding CLIs, including Claude Code, Gemini CLI, and Cursor, and installs via a single Python script with no external dependencies. Users can customize the blocklist and add new CLI adapters with minimal effort.&lt;/p&gt;

&lt;h2&gt;1. Why I built Pleasantries&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/QAInsights/pleasantries" rel="noopener noreferrer"&gt;Pleasantries&lt;/a&gt; is a pre-hook script for AI coding CLIs. It blocks pleasantry-only prompts like "hi", "hello", "ok", and "thank you" before they ever reach the model.&lt;/p&gt;

&lt;p&gt;Here is the observation that started this. AI coding assistants are task tools, not chat buddies. Every "hello" still triggers a full round trip: the CLI reads it, sends it to the model, and the model replies. That is a wasted call, wasted tokens, and a small break in your flow, all for a prompt that carries no actual task.&lt;/p&gt;

&lt;p&gt;I spend a lot of my time thinking about efficiency, whether that is a load test or a model call, so this felt like an easy win to automate away.&lt;/p&gt;

&lt;h2&gt;2. How it works&lt;/h2&gt;

&lt;p&gt;The idea is simple. A hook intercepts your prompt before it reaches the model:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;You type "hi" --&amp;gt; Hook reads prompt --&amp;gt; Regex fullmatch --&amp;gt; Blocked
You type "fix auth bug" --&amp;gt; Hook reads prompt --&amp;gt; No match --&amp;gt; Prompt proceeds
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Under the hood, the matcher normalizes your input (lowercase, strip punctuation, collapse whitespace) and checks if the &lt;strong&gt;entire&lt;/strong&gt; prompt is a pleasantry using a fullmatch, not a partial match. That distinction matters a lot. Prompts that contain a pleasantry word but also carry a real task pass through untouched.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F08%2Fimage-5-1024x589.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F08%2Fimage-5-1024x589.png" alt="" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each CLI has its own way of blocking a prompt once the hook decides to reject it, as shown below:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Block method&lt;/th&gt;
&lt;th&gt;CLIs&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;stderr + exit code 2&lt;/td&gt;
&lt;td&gt;Claude, Kiro, Copilot Chat, Copilot CLI, Cursor, Factory Droid, Kimi Code, Devin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON &lt;code&gt;{"decision": "block"}&lt;/code&gt; + exit 0&lt;/td&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON &lt;code&gt;{"decision": "deny"}&lt;/code&gt; + exit 0&lt;/td&gt;
&lt;td&gt;Gemini&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;3. Which AI coding CLIs are supported&lt;/h2&gt;

&lt;p&gt;Pleasantries currently hooks into 15 CLIs, including Claude Code, Codex CLI, Gemini CLI, Cursor, Copilot Chat, Copilot CLI, Qwen Code, Junie CLI, Factory Droid, Kimi Code, grok-cli, Kun, Open Interpreter, Kiro, and Devin CLI.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F08%2Fimage-3-1024x460.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F08%2Fimage-3-1024x460.png" alt="" width="799" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few tools do not have a hook system to plug into yet, so they are not supported: CodeBuddy, OpenCode, Aider, Kilo Code, Trae, Hermes, Pi, OpenClaw, Amp, Google Antigravity, Cline, oh-my-pi, Freebuff, and Command Code.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F08%2Fimage-4-1024x615.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F08%2Fimage-4-1024x615.png" alt="" width="799" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;4. A quick example&lt;/h2&gt;

&lt;p&gt;Say you fire up Claude Code and type "hi" out of habit before getting to your real ask. With the hook installed, that prompt never reaches the model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Prompt&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hi&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;thank you so much&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fix the login bug&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hello world program in python&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice the last two rows. "hello world program in python" contains the word hello, but it is clearly a real task, so it sails through. That fullmatch logic is what keeps this from being an annoying false-positive machine.&lt;/p&gt;

&lt;h2&gt;5. Installing it in under a minute&lt;/h2&gt;

&lt;p&gt;Head to &lt;a href="https://github.com/QAInsights/pleasantries" rel="noopener noreferrer"&gt;github.com/QAInsights/pleasantries&lt;/a&gt; and clone the repo. Then run the installer:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python install.py
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The installer will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy &lt;code&gt;block_pleasantries.py&lt;/code&gt; to &lt;code&gt;~/.pleasantries/&lt;/code&gt;
&lt;/li&gt;



&lt;li&gt;Detect which AI coding CLIs are installed on your machine&lt;/li&gt;



&lt;li&gt;Let you pick which ones to hook&lt;/li&gt;



&lt;li&gt;Merge the hook into each CLI's config, skipping anything already installed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you would rather wire it up by hand, here is the Claude Code config as an example. Add this to &lt;code&gt;~/.claude/settings.json&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "hooks": {
    "UserPromptSubmit": [
      { "hooks": [{ "type": "command",
          "command": "python3 /path/to/block_pleasantries.py claude",
          "timeout": 5 }] }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Swap in the real path to &lt;code&gt;block_pleasantries.py&lt;/code&gt;, and you are set. Every other supported CLI follows the same pattern with its own config file, all documented in the README.&lt;/p&gt;

&lt;p&gt;To remove every hook later:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python install.py --uninstall
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Requirements are light: Python 3.10+, no external dependencies beyond the standard library (&lt;code&gt;json&lt;/code&gt;, &lt;code&gt;re&lt;/code&gt;, &lt;code&gt;sys&lt;/code&gt;), and it runs on macOS, Linux, and Windows.&lt;/p&gt;

&lt;h2&gt;6. Customizing the blocklist&lt;/h2&gt;

&lt;p&gt;The blocklist lives in the &lt;code&gt;PLEASANTRY_PATTERNS&lt;/code&gt; regex inside &lt;code&gt;block_pleasantries.py&lt;/code&gt;, grouped by category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Greetings&lt;/strong&gt;: hi, hello, hey, howdy, good morning, and similar&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Acknowledgments&lt;/strong&gt;: ok, sure, yeah, got it&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Thanks&lt;/strong&gt;: thank you, thanks, thx, ty&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Please&lt;/strong&gt;: please, pls, plz&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Farewells&lt;/strong&gt;: bye, goodbye, see ya, later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your team has its own shorthand, like a Slack-style "yo" or "np", just add it to the matching category and the hook picks it up on the next run.&lt;/p&gt;

&lt;p&gt;Adding support for a brand new CLI is just as simple, since the core matcher is CLI-agnostic and each CLI only needs a small adapter function to plug into the shared &lt;code&gt;ADAPTERS&lt;/code&gt; dict.&lt;/p&gt;

&lt;h2&gt;7. Wrap up&lt;/h2&gt;

&lt;p&gt;Pleasantries is a small tool solving a small but real problem. If you run multiple AI coding CLIs day to day and catch yourself typing "hi" before your actual ask, this hook quietly saves you a wasted model call every single time.&lt;/p&gt;

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

&lt;p&gt;Do you type greetings to your AI coding assistant out of habit too, or am I the only one guilty of that?&lt;/p&gt;





</description>
      <category>ai</category>
      <category>beginners</category>
      <category>cli</category>
      <category>llm</category>
    </item>
    <item>
      <title>Mixture of Experts (MoE) Explained</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:54:49 +0000</pubDate>
      <link>https://dev.to/qainsights/mixture-of-experts-moe-explained-44np</link>
      <guid>https://dev.to/qainsights/mixture-of-experts-moe-explained-44np</guid>
      <description>&lt;p&gt;If you've used Mixtral, DeepSeek, or heard that GPT-4o uses a "Mixture of Experts" architecture, you've encountered one of the biggest efficiency breakthroughs in modern AI. MoE lets models scale to trillions of parameters while keeping inference costs manageable, because it activates only a small fraction of the network for any given input.&lt;/p&gt;

&lt;p&gt;Key benefits include scalability, lower per-request compute, and potential specialization across input types. Known challenges include load balancing across experts and added infrastructure complexity. Production implementations include Google's Switch Transformer, Mistral's Mixtral, and DeepSeek-V3, with practical implications for inference cost, latency, and fine-tuning strategies.&lt;/p&gt;

&lt;p&gt;Mixture of Experts (MoE) is a machine learning architecture that divides a model into specialized subnetworks called experts, with a gating network routing each input token to only the most relevant subset. This sparse activation approach allows models to scale to trillions of parameters while keeping inference compute costs proportional to active parameters rather than total model size.&lt;/p&gt;

&lt;h2&gt;What Is Mixture of Experts&lt;/h2&gt;

&lt;p&gt;Mixture of Experts is a machine learning architecture that divides a model into multiple specialized subnetworks called "experts," with a gating network (or router) deciding which experts should handle each input. Instead of running every parameter for every token as dense models do MoE selectively activates only the most relevant experts, making it a sparse activation technique.&lt;/p&gt;

&lt;p&gt;A simple analogy: imagine a classroom where some students excel at math, others at writing, and others at science. Rather than asking every student to answer every question, a "gate" routes each question to the student best suited to answer it. That's the core intuition behind MoE specialization plus selective routing.&lt;/p&gt;

&lt;h2&gt;Core Components of MoE Architecture&lt;/h2&gt;

&lt;p&gt;MoE layers typically replace the feedforward network (FFN) portion of a transformer block, and consist of three key pieces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experts: Independent feedforward neural networks, each capable of specializing in different patterns in the data&lt;/li&gt;



&lt;li&gt;Gating network (router): A smaller network that looks at the input and computes scores to decide which experts are best suited to handle it&lt;/li&gt;



&lt;li&gt;Sparse activation: Only the top-k experts (commonly the top 1 or 2) are activated per token, rather than running the entire set of experts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mathematically, for an input x, the output is a weighted sum of selected experts' outputs, where the gate G(x) assigns a weight to each expert Ei(x), and only a few experts are actually chosen.&lt;/p&gt;

&lt;h2&gt;How MoE Works Step by Step&lt;/h2&gt;

&lt;p&gt;The MoE process follows a consistent flow inside a transformer layer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An input token enters the transformer layer&lt;/li&gt;



&lt;li&gt;The gating network computes scores for every available expert based on the token&lt;/li&gt;



&lt;li&gt;The top-k experts (highest-scoring ones) are selected&lt;/li&gt;



&lt;li&gt;The token is routed only to those selected experts the rest stay idle for that token&lt;/li&gt;



&lt;li&gt;Each activated expert processes the token independently&lt;/li&gt;



&lt;li&gt;Their outputs are combined into a weighted sum based on the gate's confidence scores&lt;/li&gt;



&lt;li&gt;This combined output continues through the rest of the network&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Over training, the gating network learns to make better routing decisions if it picks a suboptimal expert, it adjusts itself to improve future choices.&lt;/p&gt;

&lt;h2&gt;A Simple Worked Example&lt;/h2&gt;

&lt;p&gt;Say you feed the sentence "Scale this API horizontally without causing db bottleneck" into an MoE-based model with three experts: one that leans toward cloud/deployment concepts, one that leans toward scaling concepts, and one that leans toward db patterns.&lt;/p&gt;

&lt;p&gt;The router might compute something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expert 1 (deployment-leaning): high relevance score&lt;/li&gt;



&lt;li&gt;Expert 2 (scaling-leaning): moderate relevance score&lt;/li&gt;



&lt;li&gt;Expert 3 (db): low relevance score&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the model uses top-2 routing, only Experts 1 and 2 get activated for this token, while Expert 3 stays dormant. Their outputs are combined into a weighted sum, and that becomes the token's representation moving forward. Instead of activating all available experts, only 2 out of 3 fired — and in real large-scale models, that ratio can be far more dramatic, such as 8 experts activated out of 64.&lt;/p&gt;

&lt;h2&gt;MoE vs Dense Models&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Dense Model&lt;/th&gt;
&lt;th&gt;MoE Model&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Parameter activation&lt;/td&gt;
&lt;td&gt;All parameters run for every input&lt;/td&gt;
&lt;td&gt;Only top-k experts activate per token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compute cost per inference&lt;/td&gt;
&lt;td&gt;Scales with total parameter count&lt;/td&gt;
&lt;td&gt;Scales with active parameters only, not total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Harder to scale due to compute cost&lt;/td&gt;
&lt;td&gt;Can scale to trillions of parameters efficiently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specialization&lt;/td&gt;
&lt;td&gt;Single network learns everything&lt;/td&gt;
&lt;td&gt;Experts can specialize in different patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Benefits of MoE&lt;/h2&gt;

&lt;p&gt;MoE architectures deliver several practical advantages that explain their adoption in frontier models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Massive scalability, enabling models with far larger total parameter counts than dense architectures could practically support&lt;/li&gt;



&lt;li&gt;Lower inference compute per request, since only a subset of the network activates&lt;/li&gt;



&lt;li&gt;Specialization, which can improve quality on certain types of inputs&lt;/li&gt;



&lt;li&gt;Efficient training relative to a dense model of similar total capacity, due to sparse activation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Challenges and Trade-offs&lt;/h2&gt;

&lt;p&gt;MoE isn't without complexity. A major known issue is load balancing without safeguards, the router can disproportionately favor a few experts, leaving others underused, a problem researchers address with auxiliary load-balancing losses and techniques like router z-loss for training stability. There's also added infrastructure complexity: distributing experts across devices introduces communication overhead, and interestingly, research has found that what individual experts actually learn to specialize in isn't always intuitive or human-interpretable.&lt;/p&gt;

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

&lt;p&gt;Several production and research systems have popularized MoE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch Transformer (Google Research), one of the foundational sparsely-gated MoE architectures&lt;/li&gt;



&lt;li&gt;Mixtral (Mistral AI), a widely used open MoE model&lt;/li&gt;



&lt;li&gt;DeepSeek MoE and DeepSeek-V3, which introduced refinements like fine-grained experts and auxiliary-loss-free load balancing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Minimal MoE Layer (PyTorch-style)&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;# AI Generated

import torch
import torch.nn as nn
import torch.nn.functional as F

class Expert(nn.Module):
    """A single expert: just a small feedforward network"""
    def __init__(self, dim, hidden_dim):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, dim)
        )

    def forward(self, x):
        return self.net(x)


class MoELayer(nn.Module):
    """
    A simple top-k Mixture of Experts layer
    """
    def __init__(self, dim, hidden_dim, num_experts, top_k=2):
        super().__init__()
        self.num_experts = num_experts
        self.top_k = top_k

        # The "gating network" / router
        self.gate = nn.Linear(dim, num_experts)

        # The pool of experts
        self.experts = nn.ModuleList([
            Expert(dim, hidden_dim) for _ in range(num_experts)
        ])

    def forward(self, x):
        # x shape: (batch_size, dim)

        # Step 1: Router computes scores for each expert
        gate_logits = self.gate(x)                      # (batch, num_experts)
        gate_scores = F.softmax(gate_logits, dim=-1)

        # Step 2: Pick top-k experts per token
        topk_scores, topk_idx = torch.topk(gate_scores, self.top_k, dim=-1)

        # Normalize the selected scores so they sum to 1
        topk_scores = topk_scores / topk_scores.sum(dim=-1, keepdim=True)

        output = torch.zeros_like(x)

        # Step 3: Route each token only to its selected experts
        for i in range(self.top_k):
            expert_idx = topk_idx[:, i]        # which expert for this slot
            expert_weight = topk_scores[:, i]  # confidence weight

            for e in range(self.num_experts):
                mask = (expert_idx == e)
                if mask.any():
                    expert_output = self.experts[e](x[mask])
                    output[mask] += expert_weight[mask].unsqueeze(-1) * expert_output

        # Step 4: Combine outputs (already summed above as weighted sum)
        return output
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Why This Matters for Developers&lt;/h2&gt;

&lt;p&gt;If you're building LLM-powered applications, MoE directly affects cost and latency, since inference cost tracks active parameters rather than total model size. If you're working on inference infrastructure, expert routing and load balancing become real engineering concerns, not just theoretical details. And if you're exploring fine-tuning or model architecture design, MoE introduces distinct considerations around expert parallelism versus traditional data parallelism.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>programming</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>How Does an LLM Request and Response Cycle Work? A Full Walkthrough</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Mon, 20 Jul 2026 23:36:59 +0000</pubDate>
      <link>https://dev.to/qainsights/how-does-an-llm-request-and-response-cycle-work-a-full-walkthrough-2k7j</link>
      <guid>https://dev.to/qainsights/how-does-an-llm-request-and-response-cycle-work-a-full-walkthrough-2k7j</guid>
      <description>&lt;p&gt;In this blog post, we will see how an LLM request and response cycle works, from the second you hit send to the moment the last word lands on your screen. I will not throw a wall of transformer math at you. Instead, we will follow one single prompt through every stage of the journey, so nothing feels abstract.&lt;/p&gt;

&lt;p&gt;A single prompt sent to a large language model passes through multiple distinct stages before a response appears on screen. The process begins with the client app building a structured JSON request, which then clears an API gateway before the input text is broken into numeric tokens and assembled into the model's context window.&lt;/p&gt;

&lt;p&gt;The model then runs a forward pass through transformer layers to predict one token at a time, repeating this loop until an end-of-sequence signal is reached. Tokens stream back to the client as they are produced and are converted back into readable text incrementally, which explains the word-by-word appearance of responses.&lt;/p&gt;

&lt;p&gt;I got curious about mapping this out properly while building iamspeed.dev, my browser based LLM benchmarking tool. Before I could measure things like tokens per second or time to first token, I had to understand exactly what happens between "you press Enter" and "words start appearing." Turns out that gap has a lot more steps than most people assume.&lt;/p&gt;

&lt;h2&gt;The example we will follow&lt;/h2&gt;

&lt;p&gt;Let's keep one example running through the whole post. Say you type this into a chat app:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; What's the capital of India?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And a few seconds later, the model replies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Assistant:&lt;/strong&gt; The capital of India is New Delhi.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simple enough on the surface. But that one exchange touches a client app, an API layer, a tokenizer, a neural network with billions of parameters, a sampling algorithm, and a streaming pipeline, all before those six words show up in your chat window. Let's go step by step.&lt;/p&gt;

&lt;h2&gt;Step 1: You hit send&lt;/h2&gt;

&lt;p&gt;The moment you press Enter, your chat app does not just fire off the raw sentence. It builds a structured request, usually JSON, that looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "model": "some-llm-model",
  "messages": [
    { "role": "system", "content": "You are a helpful assistant." },
    { "role": "user", "content": "What's the capital of India?" }
  ],
  "temperature": 0.7,
  "max_tokens": 100,
  "stream": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice a few things here. The system prompt is bundled in even though you never typed it. Any earlier messages in the conversation get bundled in too, since the model has no memory of its own between calls. And &lt;code&gt;stream: true&lt;/code&gt; is already set, which matters a lot later. This payload gets sent over HTTPS to an API endpoint.&lt;/p&gt;

&lt;h2&gt;Step 2: The API gateway&lt;/h2&gt;

&lt;p&gt;Your request does not go straight to a model. It first hits an API gateway that handles the boring but essential stuff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validating your API key or session token&lt;/li&gt;



&lt;li&gt;Checking rate limits, so nobody floods the system&lt;/li&gt;



&lt;li&gt;Routing the request to the right model version and the right compute cluster, often based on region for lower latency&lt;/li&gt;



&lt;li&gt;Logging the request for billing and abuse monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of this layer as the bouncer and the traffic cop combined. Only after it clears the request does anything resembling "AI" actually happen.&lt;/p&gt;

&lt;h2&gt;Step 3: Tokenization&lt;/h2&gt;

&lt;p&gt;Here is where things get interesting. The model does not read English. It reads tokens, which are chunks of text mapped to numbers. A tokenizer breaks your sentence apart, usually using a scheme like byte pair encoding.&lt;/p&gt;

&lt;p&gt;Our example sentence, "What's the capital of India?", might get tokenized into something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;["What", "'s", " the", " capital", " of", " India", "?"]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each of these chunks maps to a specific integer ID from the model's vocabulary, something like &lt;code&gt;[1780, 434, 262, 3139, 286, 4881, 30]&lt;/code&gt;. The exact split depends on the tokenizer the model uses, but the idea is always the same: text becomes numbers, because that is the only thing a neural network can actually compute on.&lt;/p&gt;

&lt;p&gt;This step matters more than people realize. It is also why providers bill you per token instead of per word or per character. A short word can be one token, a rare word can be split into three or four.&lt;/p&gt;

&lt;h2&gt;Step 4: Building the context window&lt;/h2&gt;

&lt;p&gt;Your new tokens do not go in alone. The system stitches together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The system prompt tokens&lt;/li&gt;



&lt;li&gt;Any prior conversation history tokens&lt;/li&gt;



&lt;li&gt;Your new message tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this gets packed into the model's context window, which is just a fancy term for "how many tokens the model can look at in one shot." Each token also gets a positional encoding attached, so the model knows word order, since without it, "India of capital the" and "capital of India" would look identical to the network.&lt;/p&gt;

&lt;h2&gt;Step 5: The forward pass&lt;/h2&gt;

&lt;p&gt;Now the actual model runs. Your token sequence flows through dozens of transformer layers stacked on top of each other. Inside each layer, two things happen repeatedly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-attention&lt;/strong&gt;, where every token looks at every other token in the sequence and decides how much to "pay attention" to it. This is how the model knows that "capital" relates to "India" and not to some other country mentioned three messages ago.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Feed-forward processing&lt;/strong&gt;, where each token's representation gets transformed further, layer after layer, refining what the model "understands" about the sequence so far.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After all layers, the model produces a probability distribution over its entire vocabulary, essentially a ranked guess of what the very next token should be. For our example, after processing "What's the capital of India?", the model's internal state is now primed to predict something like "The" as a strong first candidate.&lt;/p&gt;

&lt;h2&gt;Step 6: Sampling the next token&lt;/h2&gt;

&lt;p&gt;Here is the part that surprises people the first time they learn it: the model does not generate the whole sentence at once. It generates one token, feeds that token back into itself as part of the input, and generates the next one. This repeats until it decides to stop.&lt;/p&gt;

&lt;p&gt;Parameters like &lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;top_p&lt;/code&gt;, and &lt;code&gt;top_k&lt;/code&gt; control how the next token gets picked from that probability distribution. Lower temperature means the model plays it safe and picks the highest probability token almost every time. Higher temperature adds randomness, useful for creative writing, less useful for factual answers.&lt;/p&gt;

&lt;p&gt;For our example, the autoregressive loop looks roughly like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Input so far: "What's the capital of India?"
→ predict: "The"

Input so far: "...India?" + "The"
→ predict: " capital"

Input so far: "...The" + " capital"
→ predict: " of"

... and so on, until:
"The capital of India is New Delhi." + &amp;lt;end-of-sequence token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That end-of-sequence token is the model's way of saying "I am done," which is also how it knows when to stop rather than rambling forever.&lt;/p&gt;

&lt;h2&gt;Step 7: Streaming the response back&lt;/h2&gt;

&lt;p&gt;Remember &lt;code&gt;stream: true&lt;/code&gt; from Step 1? This is where it pays off. Instead of waiting for the entire response to finish generating and sending it as one big blob, the server pushes each token to your client the moment it is produced, usually over Server-Sent Events or a chunked HTTP connection.&lt;/p&gt;

&lt;p&gt;That is exactly why you see words appear on screen one at a time instead of the whole answer popping in at once. It is not a visual effect, it is literally showing you tokens as the model produces them.&lt;/p&gt;

&lt;h2&gt;Step 8: Detokenization and rendering&lt;/h2&gt;

&lt;p&gt;On the client side, each incoming token ID gets converted back into readable text, the reverse of Step 3. The chat app appends each piece to the message bubble as it arrives, re-renders the UI, and by the time the end-of-sequence signal shows up, you are looking at the complete sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The capital of India is New Delhi.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Six words. Eight steps. All of it usually finishing in under two seconds.&lt;/p&gt;

&lt;h2&gt;Where latency actually lives&lt;/h2&gt;

&lt;p&gt;Given my performance engineering background, I cannot write this post without pointing at the clock. Two numbers matter a lot more than "the response took 3 seconds":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time to first token (TTFT)&lt;/strong&gt;: how long you wait between hitting send and seeing the very first word appear. This is dominated by Steps 1 through 5, especially the forward pass on a long context window.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Inter-token latency&lt;/strong&gt;: how quickly tokens keep arriving after the first one, which shapes how "smooth" the typing effect feels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A model can have a slow TTFT but fast inter-token speed, or the reverse, and the two create very different user experiences even if the total time is identical. This is the exact gap I was trying to measure when building iamspeed.dev, and honestly, understanding this full life cycle is what made the benchmarking numbers actually make sense instead of just being numbers on a dashboard.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Check &lt;a href="https://iamspeed.dev" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt; to measure the LLM performance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Wrap up&lt;/h2&gt;

&lt;p&gt;So the next time you type a question into a chat app and watch the answer type itself out, you now know the full trip that sentence takes: request formation, gateway checks, tokenization, context assembly, a forward pass through a massive network, token-by-token sampling, streaming, and finally detokenization back into words you can read.&lt;/p&gt;

&lt;p&gt;It looks like magic from the outside. From the inside, it is a very well engineered pipeline.&lt;/p&gt;

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

&lt;p&gt;Have you ever watched an LLM response stream in and wondered what was happening under the hood? Let me know in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>llm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Leitner Loop - AWS Cert Pilot</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Mon, 20 Jul 2026 14:36:37 +0000</pubDate>
      <link>https://dev.to/qainsights/leitner-loop-aws-cert-pilot-1cel</link>
      <guid>https://dev.to/qainsights/leitner-loop-aws-cert-pilot-1cel</guid>
      <description>&lt;h2&gt;&lt;strong&gt;Vision &amp;amp; What the Agent Does&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Studying for an AWS certification usually means remembering to sit down, open a study app, and grind through flashcards and that habit dies the moment life gets busy. &lt;strong&gt;Leitner Loop&lt;/strong&gt; removes the "open the app" step entirely. It's an always-on study partner that runs on its own schedule, decides what you need to review next, writes brand-new practice questions for it, and emails them to you no button click required.&lt;/p&gt;

&lt;p&gt;Leitner Loop is an automated AWS certification study tool that runs on a scheduled basis, requiring no manual interaction. Every two hours, EventBridge Scheduler triggers a Lambda function that identifies due review topics using a five-box spaced-repetition system, generates fresh multiple-choice questions via Amazon Bedrock, and delivers them by email through SES with clickable answer links.&lt;/p&gt;

&lt;p&gt;Clicking an answer routes through API Gateway to a second Lambda that grades the response, provides an explanation, and updates the topic's review schedule in DynamoDB. Key implementation challenges included defensively parsing Bedrock's JSON output and adapting to AWS's deprecation of direct model ID invocation in favor of cross-region inference profiles.&lt;/p&gt;

&lt;p&gt;Every two hours, an EventBridge Scheduler rule triggers the agent. It checks a DynamoDB table of exam topics for whichever ones are "due" for review (using a Leitner spaced-repetition schedule), asks Amazon Bedrock (Claude Haiku 4.5) to generate up to 10 fresh, scenario-based multiple-choice questions across those due topics, and emails them to me via SES &amp;nbsp;each answer option is a clickable link. &lt;/p&gt;

&lt;p&gt;When I click an answer from my inbox, API Gateway routes it to a second Lambda that grades it, shows the correct answer and explanation, and reschedules that topic further out (if correct) or back to square one (if wrong). It reports back the only way that matters when you're away from the keyboard: an email waiting for you, and a running record of what you actually know.&lt;/p&gt;

&lt;h2&gt;The Leitner System&lt;/h2&gt;

&lt;p&gt;It's a classic &lt;strong&gt;spaced-repetition study technique&lt;/strong&gt; (invented by Sebastian Leitner in the 1970s using physical flashcard boxes). The core idea: things you know well get reviewed less often, things you get wrong get reviewed again soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works, generically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cards live in numbered "boxes" (1 = review most often, 5 = review least often).&lt;/li&gt;



&lt;li&gt;Answer correctly ? card moves to the next box up (longer interval before it's due again).&lt;/li&gt;



&lt;li&gt;Answer incorrectly ? card drops back to box 1 (reviewed again soon).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How agent implements it&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;BOX_INTERVALS = {1: 1, 2: 3, 3: 7, 4: 14, 5: 30}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each exam topic has a &lt;code&gt;box&lt;/code&gt; (1–5) and a &lt;code&gt;next_due&lt;/code&gt; date stored in DynamoDB. When you answer a question:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Correct&lt;/strong&gt; ? &lt;code&gt;box = min(box + 1, 5)&lt;/code&gt; — moves up a box, next review pushed further out (1 ? 3 ? 7 ? 14 ? 30 days).&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Incorrect&lt;/strong&gt; ? &lt;code&gt;box = 1&lt;/code&gt; — resets to daily review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So "Leitner Loop" is the agent's name because the whole thing &lt;em&gt;is&lt;/em&gt; an automated, always-running loop of that Leitner box system: &lt;code&gt;lambda_quiz_generator.py&lt;/code&gt; picks topics that are due (&lt;code&gt;next_due &amp;lt;= today&lt;/code&gt;) every 2 hours and generates questions for them; answering them via &lt;code&gt;lambda_grading_handler.py&lt;/code&gt; feeds the box/interval update back into DynamoDB, which determines what the &lt;em&gt;next&lt;/em&gt; run picks. &lt;/p&gt;

&lt;p&gt;That closed feedback loop — pick due topics ? quiz ? grade ? reschedule ? repeat  is the "loop" in the name.&lt;/p&gt;

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

&lt;p&gt;The core design decision was splitting the agent into two single-purpose Lambdas &amp;nbsp;&lt;code&gt;quiz-generator&lt;/code&gt; and &lt;code&gt;grading-handler&lt;/code&gt; each with its own IAM role and least-privilege inline policy, rather than one monolithic function. This kept the "generate" path (Bedrock + SES + writes) cleanly separated from the "grade" path (reads + updates triggered by an untrusted public URL click), which also made reasoning about security boundaries much simpler.&lt;/p&gt;

&lt;p&gt;The trickiest part was making Bedrock's output reliable enough to parse automatically every run. Claude occasionally wraps JSON in markdown code fences or adds stray text, so &lt;code&gt;generate_question()&lt;/code&gt; strips backticks and a leading &lt;code&gt;json&lt;/code&gt; tag before parsing &amp;nbsp;a small defensive step that turned an intermittent failure into a non-issue. I also had to work around AWS deprecating direct invocation of newer Claude model IDs; the fix was switching to a &lt;code&gt;us.&lt;/code&gt;-prefixed cross-region inference profile ID instead of a bare model ID.&lt;/p&gt;

&lt;p&gt;For the spaced repetition itself, I used a classic &lt;strong&gt;5-box Leitner scheme&lt;/strong&gt; (`BOX_INTERVALS = {1:1, 2:3, 3:7, 4:14, 5:30}` days) &amp;nbsp;simple, well-understood, and easy to tune. Switching which certification the agent studies is just a one-line change to the EventBridge target's input payload &lt;strong&gt;(`{"cert_code": "SAA-C03"}`)&lt;/strong&gt;, no redeploy needed, since all cert-specific data (exam domains, topic names) lives in DynamoDB via &lt;code&gt;seed_topics.py&lt;/code&gt; rather than in code.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;AWS Services Used / Architecture Overview&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Services:&lt;/strong&gt; Amazon EventBridge Scheduler, AWS Lambda (2 functions), Amazon Bedrock (Claude Haiku 4.5 via cross-region inference profile), Amazon SES, Amazon API Gateway (HTTP API), Amazon DynamoDB (2 tables), AWS IAM.&lt;/p&gt;

&lt;p&gt;Both DynamoDB tables use on-demand billing and stay within the AWS Free Tier. TTL on `cert-quiz-pending` auto-expires unanswered questions after 48 hours so nothing lingers. The trigger is entirely schedule-driven &amp;nbsp;I never open an app; the agent decides on its own whether there's anything worth sending.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Farch-682x1024.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Farch-682x1024.png" alt="" width="682" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Cost&lt;/h2&gt;

&lt;p&gt;Based on current AWS pricing (all &lt;code&gt;us-east-1&lt;/code&gt;), assuming the default &lt;code&gt;rate(2 hours)&lt;/code&gt; schedule (max 12 runs/day) and up to 10 questions/email:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Pricing&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;th&gt;Est. Monthly Cost&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EventBridge Scheduler&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$1.00/million invocations after 14M free&lt;/td&gt;
&lt;td&gt;~360 invocations/mo&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0.00&lt;/strong&gt; (free tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lambda (2 functions)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0.20/million requests + $0.0000166667/GB-s; free tier: 1M req + 400K GB-s/mo&lt;/td&gt;
&lt;td&gt;~4K invocations/mo, short duration&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0.00&lt;/strong&gt; (free tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon Bedrock (Claude Haiku 4.5)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$1.00/1M input tokens, $5.00/1M output tokens&lt;/td&gt;
&lt;td&gt;~120 calls/day worst case (~800 in / 300 out tokens each) ? ~2.9M input + 1.1M output tokens/mo&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$3–$9/month&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amazon SES&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0.10/1,000 emails; 3,000 free/mo for first 12 months&lt;/td&gt;
&lt;td&gt;?360 emails/mo&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.00–$0.04&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Gateway (HTTP API)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$1.00/million requests; 1M free/mo for 12 months&lt;/td&gt;
&lt;td&gt;Few hundred requests/mo&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.00&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DynamoDB (on-demand, 2 tables)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$1.25/million WRUs, $0.25/million RRUs&lt;/td&gt;
&lt;td&gt;Low hundreds of ops/mo&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$0.01&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CloudWatch Logs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free tier: 5GB ingestion/mo&lt;/td&gt;
&lt;td&gt;Minimal log volume&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.00&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Total: &lt;strong&gt;? $3–$10/month&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cost driver:&lt;/strong&gt; Bedrock dominates almost entirely. The range depends on how often topics are actually "due" the Leitner reschedule logic means most 2-hour runs are silent (no due topics), so real-world cost is likely closer to the &lt;strong&gt;$1–$3/month&lt;/strong&gt; range unless you're actively answering and cycling through many topics daily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All other services stay within their AWS Free Tier for this workload, so they're effectively &lt;strong&gt;$0&lt;/strong&gt;.&lt;/li&gt;



&lt;li&gt;First-year SES free tier (3,000 messages/mo) and Lambda's &lt;em&gt;permanent&lt;/em&gt; free tier further reduce costs  Lambda's 1M requests/400K GB-s allowance never expires.&lt;/li&gt;



&lt;li&gt;Sources: &lt;code&gt;aws.amazon.com/bedrock/pricing&lt;/code&gt;, &lt;code&gt;aws.amazon.com/lambda/pricing&lt;/code&gt;, &lt;code&gt;aws.amazon.com/eventbridge/pricing&lt;/code&gt;, &lt;code&gt;aws.amazon.com/ses/pricing&lt;/code&gt;, &lt;code&gt;aws.amazon.com/api-gateway/pricing&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Screenshots&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Femail-713x1024.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Femail-713x1024.png" alt="" width="713" height="1024"&gt;&lt;/a&gt;&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fcorrect-answer-1024x212.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fcorrect-answer-1024x212.png" alt="" width="800" height="166"&gt;&lt;/a&gt;&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fincorrect-answer-1024x270.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fincorrect-answer-1024x270.png" alt="" width="800" height="211"&gt;&lt;/a&gt;&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fevent-bridge-1024x424.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fevent-bridge-1024x424.png" alt="" width="799" height="331"&gt;&lt;/a&gt;&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fcloudwatch-quiz-1024x924.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fcloudwatch-quiz-1024x924.png" alt="" width="800" height="722"&gt;&lt;/a&gt;&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fcloudwatch-grading-1024x706.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fcloudwatch-grading-1024x706.png" alt="" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Building this reinforced how much reliability work goes into &lt;strong&gt;"just call an LLM"&lt;/strong&gt; once it's unattended &amp;nbsp;validating and defensively parsing model output matters far more when there's no human in the loop to notice a malformed response. &lt;/p&gt;

&lt;p&gt;I also learned the hard way that AWS retires direct base-model-ID invocation for newer Bedrock models in favor of cross-region inference profiles, and that IAM policy changes don't always take effect on warm Lambda execution environments immediately. &lt;/p&gt;

&lt;p&gt;On the architecture side, designing around DynamoDB TTL for ephemeral state (pending answers) turned out to be a clean, zero-maintenance way to handle&lt;strong&gt; "expire after N hours"&lt;/strong&gt; without a cleanup job.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agentskills</category>
      <category>aws</category>
    </item>
    <item>
      <title>$20/Month: The Price Ceiling Every AI Company Copied</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Sat, 18 Jul 2026 18:37:47 +0000</pubDate>
      <link>https://dev.to/qainsights/20month-the-price-ceiling-every-ai-company-copied-1jej</link>
      <guid>https://dev.to/qainsights/20month-the-price-ceiling-every-ai-company-copied-1jej</guid>
      <description>&lt;p&gt;In this blog post, we will see why almost every major AI subscription, ChatGPT, Claude, Perplexity, and Gemini, somehow landed on the exact same $20 a month price tag. We will trace it back to where it started, look at the actual reasoning behind the number, and figure out whether this price ceiling will hold or eventually crack the way streaming subscriptions did.&lt;/p&gt;

&lt;p&gt;The $20 monthly price point shared by ChatGPT Plus, Claude Pro, Perplexity Pro, and Google AI Pro traces back to OpenAI's February 2023 launch, which was designed to subsidize free-tier costs rather than reflect the actual value of the product. Competitors adopted the number through price anchoring, not independent cost analysis.&lt;/p&gt;

&lt;p&gt;The same pattern has extended to smaller AI tools and is now repeating at higher tiers, with $200 and $100 monthly plans emerging for power users. Despite identical pricing, what each $20 subscription delivers varies significantly across providers in terms of usage limits, features, and model access.&lt;/p&gt;

&lt;h2&gt;The Coincidence That Isn't a Coincidence&lt;/h2&gt;

&lt;p&gt;As of mid-2026, ChatGPT Plus, Claude Pro, and Perplexity Pro all cost exactly $20 a month. Google AI Pro (formerly Gemini Advanced) sits one cent below at $19.99. Four completely different companies, four completely different models, and yet the sticker price converges on almost the same number. &lt;/p&gt;

&lt;p&gt;That's not four companies independently landing on the same cost math. It's one company setting a price, and everyone else deciding not to compete on it.&lt;/p&gt;

&lt;h2&gt;Where It Actually Started: OpenAI, February 2023&lt;/h2&gt;

&lt;p&gt;ChatGPT launched free in November 2022 and crossed a million users within about a month, which was an enormous number for a research preview. On February 1, 2023, OpenAI introduced ChatGPT Plus at $20 a month, expanding it internationally on February 10. The pitch at the time was simple: general access even during peak load, faster responses, and priority access to new features.&lt;/p&gt;

&lt;p&gt;Worth remembering: this was the GPT-3.5 era. GPT-4 hadn't shipped yet. Subscribers in February 2023 were paying $20 for a noticeably weaker model than what free users get today. The price has not moved since, even as that same $20 has quietly absorbed GPT-4, several GPT-5 generations, Deep Research, Sora video, Codex, and agent mode.&lt;/p&gt;

&lt;h2&gt;The Real Reason Behind $20&lt;/h2&gt;

&lt;p&gt;OpenAI wasn't shy about why Plus existed. Running ChatGPT was expensive, Sam Altman described the compute costs as substantial even at a few cents per conversation, and the company was under real pressure to make the free product sustainable. OpenAI itself said the subscription revenue existed partly to keep free access available to as many people as possible.&lt;/p&gt;

&lt;p&gt;Put plainly, $20 wasn't calculated as "what is a fair price for this capability." It was closer to "what can we charge a subset of engaged users so the free tier doesn't bankrupt us." OpenAI was reportedly expecting around $200 million in revenue for 2023, against more than a billion dollars already invested in the company. The $20 tier was a stopgap, not a value calculation.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fimage-4-1024x538.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F07%2Fimage-4-1024x538.png" alt="" width="799" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;The Copycat Effect&lt;/h2&gt;

&lt;p&gt;Once ChatGPT Plus proved people would pay $20 without mass cancellations, every serious competitor used that number as their starting point instead of testing their own.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Pro&lt;/strong&gt; launched at $20/month (with a modest annual discount).&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Perplexity Pro&lt;/strong&gt; launched at $20/month.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Google AI Pro&lt;/strong&gt; priced itself at $19.99, a classic one-cent-under-the-anchor move rather than an independent price.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Grok's SuperGrok&lt;/strong&gt; is the outlier at $30/month, positioned above the pack rather than matching it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these companies share OpenAI's cost structure. Different model sizes, different infrastructure, different margins. But none of them wanted to be the one charging more for what would look like a worse deal, and none of them needed to undercut a price users had already accepted. That's price anchoring playing out at the scale of an entire industry.&lt;/p&gt;

&lt;h2&gt;It's Not Just the Big Four&lt;/h2&gt;

&lt;p&gt;This isn't only an OpenAI-versus-Anthropic-versus-Google story. Scroll through any random week of Product Hunt or Hacker News launches and the same number shows up over and over, on tools that have nothing to do with the frontier labs.&lt;/p&gt;

&lt;p&gt;A 2026 Product Hunt launch playbook says it outright, the AI audience on that platform has been trained by ChatGPT to expect $20/month as the ceiling. Founders pricing above that are advised to address it head-on in their launch comments. Founders pricing below it, or offering a real free tier, are told to lead with that instead, since most funded AI tools have quietly dropped their free tiers altogether.&lt;/p&gt;

&lt;p&gt;A post on Indie Hackers picking apart AI tool pricing in 2026 flagged the same pattern from the builder's side, a "weird clustering happening around the $20/month price point" across small, independently built AI products. Its explanation for why lines up with everything happening at the top of the market too, most of these tools aren't priced against what they cost to run, they're priced against what feels acceptable at a glance. Low enough that a buyer won't push back, high enough that almost nobody checks what the underlying API usage would have actually cost if billed directly instead.&lt;/p&gt;

&lt;p&gt;You can watch that anchor form in real time inside launch threads. On one Show HN post for a coding assistant priced at $20/month with a 100 message cap, a commenter said the quiet part out loud, they assumed the tool was close to unlimited at that price only because $20 a month is already what they pay for Gemini or ChatGPT, and that already feels unlimited to them. Nobody in that thread calculated $20 from cost. It was already the accepted price of "an AI subscription," so it became the price of this one too.&lt;/p&gt;

&lt;p&gt;So no, you don't need to dig very hard to confirm this yourself. Open Product Hunt's AI category on any given day, or skim a handful of recent Show HN posts pitching an AI wrapper, assistant, or agent. $20/month will be sitting right there as the default, again and again.&lt;/p&gt;

&lt;h2&gt;What $20 Actually Buys You Right Now&lt;/h2&gt;

&lt;p&gt;Here's a concrete snapshot, since "$20 a month" means very different things depending on the provider. As of mid-2026, roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT Plus&lt;/strong&gt;: around 150 messages every 3 hours on the current flagship model, plus Deep Research capped at a handful of runs a month.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Claude Pro&lt;/strong&gt;: a generous message allowance on the current flagship model, positioned around coding and long-form writing use cases.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Google AI Pro&lt;/strong&gt;: a very large context window (in the range of a million tokens), bundled with Google storage and Workspace integration.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Perplexity Pro&lt;/strong&gt;: effectively unlimited Pro searches, but Deep Research usage has been tightened over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The number on the invoice is identical. The actual product you get for that number is not even close. This is the part most comparison articles gloss over, they show you a price table and stop, without mentioning that "$20" buys you a completely different bundle of limits depending on which company you hand it to.&lt;/p&gt;

&lt;p&gt;These specific limits shift every few months as providers adjust caps, so treat the numbers above as a snapshot rather than gospel, and check the current plan page before you decide.&lt;/p&gt;

&lt;h2&gt;Why $20 and Not $10 or $30&lt;/h2&gt;

&lt;p&gt;A few analysts pricing out the AI subscription market this year converged on the same explanation: $20 a month is roughly the ceiling a typical person will tolerate for a single productivity subscription before they start looking for a reason to cancel. Below that, you leave money on the table. Above it, you start losing casual users to the free tier or to a cheaper competitor.&lt;/p&gt;

&lt;p&gt;Google AI Pro pricing at $19.99 instead of a round $20 is a small but telling detail. It's not a cost-based number, it's a psychological anchor, deliberately priced just under the number everyone else already normalized.&lt;/p&gt;

&lt;p&gt;I've watched a smaller version of this play out in my own world. I sell developer tools on Gumroad, and pricing a plugin isn't really about calculating your costs and adding a margin. It's about figuring out what the market has already decided a similar tool is "supposed to" cost, then deciding whether you sit at, above, or just under that number. AI subscriptions are doing the exact same thing, just with a few more zeroes involved.&lt;/p&gt;

&lt;h2&gt;The Next Ceiling: $100 to $200&lt;/h2&gt;

&lt;p&gt;The $20 tier isn't the top of the market anymore, it's the floor for serious usage. OpenAI introduced ChatGPT Enterprise in August 2023, ChatGPT Teams in January 2024 (later increased to $30/month), and a $200/month ChatGPT Pro tier in December 2024 aimed at unlimited access for heavy users. In April 2026, OpenAI added a $100/month Pro tier, offering the same model suite as the $200 tier at lower usage limits, a move widely read as a direct response to Anthropic's Claude Max 5x plan.&lt;/p&gt;

&lt;p&gt;The same anchoring pattern is repeating one level up. One provider sets a $200 ceiling for power users, and rather than undercutting it, competitors match it and differentiate on limits instead of price. It's the $20 story again, just with an extra zero.&lt;/p&gt;

&lt;h2&gt;My Take&lt;/h2&gt;

&lt;p&gt;The $20 price tag has become a kind of unspoken industry standard, similar to how $9.99 became the default for a certain class of consumer app subscription, or how $99 shows up everywhere in early-stage SaaS pricing. Nobody sat down and calculated $20 as the "correct" price for access to a frontier AI model. OpenAI needed it to survive, everyone else needed a reason not to compete on price, and $20 became the answer to both problems at once.&lt;/p&gt;

&lt;p&gt;Whether it holds depends entirely on compute costs. Models are getting cheaper to run per token even as they get more capable, which is the one force that could eventually push this ceiling down instead of up. But subscription businesses rarely cut prices voluntarily. My guess is the $20 tier stays exactly where it is, and all the real competition keeps happening one level up, at $100 and $200.&lt;/p&gt;

&lt;p&gt;Do you think the $20 AI subscription price holds for another few years, or does it eventually creep upward the way streaming subscriptions did? Let me know in the comments.&lt;/p&gt;

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

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Performance Testing RAG Applications: Complete Engineering Guide</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Mon, 06 Jul 2026 15:56:54 +0000</pubDate>
      <link>https://dev.to/qainsights/performance-testing-rag-applications-complete-engineering-guide-25g7</link>
      <guid>https://dev.to/qainsights/performance-testing-rag-applications-complete-engineering-guide-25g7</guid>
      <description>&lt;p&gt;In this blog post, we will see how to performance test a RAG (Retrieval-Augmented Generation) application properly, covering both speed and correctness, and how to wire both into a CI/CD pipeline so regressions get caught before they reach production.&lt;/p&gt;

&lt;p&gt;Performance testing a RAG application requires two separate testing gates: one for speed and one for answer quality. Traditional load testing tools measure response times but cannot detect hallucinations, where a model returns fast but factually incorrect answers grounded in fabricated context rather than retrieved documents.&lt;/p&gt;

&lt;p&gt;The guide demonstrates using k6 for load testing end-to-end latency and DeepEval for evaluating faithfulness and answer relevancy using an LLM-as-judge approach. Both gates are integrated into a GitHub Actions CI/CD pipeline so regressions in either performance or output quality are caught automatically on every pull request before reaching production.&lt;/p&gt;

&lt;p&gt;If you've come from a JMeter or k6 background like I have, your first instinct with a RAG endpoint is probably to point a load test at it and check response times. That gets you halfway there. A RAG app can return a fast, confident, completely wrong answer, and a plain load test will never tell you that. You need two testing surfaces, not one: performance and quality. This guide covers both, using a single running example throughout: a documentation assistant that answers "How do I run JMeter in non-GUI mode?" against a small knowledge base.&lt;/p&gt;

&lt;h2&gt;Why RAG breaks traditional load testing assumptions&lt;/h2&gt;

&lt;p&gt;A conventional API returns a complete response and you measure the round trip. A RAG endpoint does two expensive things before it answers: it retrieves context from a vector store or search index, then it streams a generated response token by token. That second part matters a lot. A single request can stream hundreds of tokens over several seconds, so "request duration" as a single number hides two very different problems: how long the model took to start answering, and how fast it generated once it started.&lt;/p&gt;

&lt;p&gt;A system with slow startup but fast generation feels broken to someone typing in a chat UI. A system with fast startup but slow generation is fine for a quick question but painful for a long document summary. Averaging those together tells you nothing useful.&lt;/p&gt;

&lt;h2&gt;The two testing surfaces: performance and quality&lt;/h2&gt;

&lt;p&gt;I think of RAG testing as two separate gates that happen to run against the same endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt; answers: how fast is it, and does it hold up under load? This is k6's job, same as any other API load test, just with LLM-specific metrics layered on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quality&lt;/strong&gt; answers: is the answer actually grounded in what got retrieved, or did the model make something up? This is where DeepEval comes in, scoring faithfulness and relevancy on every response using an LLM as the judge.&lt;/p&gt;

&lt;p&gt;Neither gate alone tells the full story. A fast RAG app that hallucinates is worse than a slow one that's accurate, and a perfectly grounded app that takes eight seconds to respond will lose users regardless of correctness.&lt;/p&gt;

&lt;h2&gt;Metrics that actually matter&lt;/h2&gt;

&lt;h3&gt;Performance metrics&lt;/h3&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;What it tells you&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TTFT (Time to First Token)&lt;/td&gt;
&lt;td&gt;How long a user stares at a blank screen before anything appears&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ITL (Inter-Token Latency)&lt;/td&gt;
&lt;td&gt;How smoothly tokens stream once generation starts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens/sec&lt;/td&gt;
&lt;td&gt;Generation speed, matters most for long-form answers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;p95 / p99 latency&lt;/td&gt;
&lt;td&gt;The tail experience, not the average one&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;TTFT is the most user-visible number in the whole system, and it's also the metric most classic load testing tools weren't built to isolate, since they were designed for atomic request/response cycles, not streams.&lt;/p&gt;

&lt;h3&gt;Quality metrics&lt;/h3&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;What it tells you&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Faithfulness&lt;/td&gt;
&lt;td&gt;Is the answer grounded in the retrieved context, or invented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Answer relevancy&lt;/td&gt;
&lt;td&gt;Does the answer address the actual question, or just sound plausible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context precision&lt;/td&gt;
&lt;td&gt;Did retrieval return the right chunks, ranked correctly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context recall&lt;/td&gt;
&lt;td&gt;Did retrieval miss anything the answer needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These four metrics carry most of the diagnostic weight in RAG evaluation. Faithfulness and answer relevancy live on the generation side; context precision and recall live on the retrieval side. When faithfulness is low but context recall is high, the retriever did its job and the model ignored it that's a prompting problem, not a retrieval problem. Worth knowing the difference before you go tuning the wrong component.&lt;/p&gt;

&lt;h2&gt;Hallucination detection with DeepEval&lt;/h2&gt;

&lt;p&gt;I'm using DeepEval here instead of RAGAS mainly because DeepEval treats evaluations as pytest test cases with pass/fail thresholds, which is exactly the shape you need for a CI/CD gate. It also accepts any LLM as the judge model, so it isn't locked to one vendor even though our example app happens to use Gemini.&lt;/p&gt;

&lt;p&gt;Here's what a test case looks like against our JMeter doc-assistant example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;from deepeval.metrics import FaithfulnessMetric, AnswerRelevancyMetric
from deepeval.test_case import LLMTestCase
from deepeval.models import GeminiModel

judge_model = GeminiModel(
    model="gemini-3.5-flash",
    api_key=os.getenv("GEMINI_API_KEY"),
)

faithfulness_metric = FaithfulnessMetric(threshold=0.75, model=judge_model)
answer_relevancy_metric = AnswerRelevancyMetric(threshold=0.8, model=judge_model)

def test_jmeter_non_gui_mode_answer():
    question = "How do I run JMeter in non-GUI mode?"
    result = query_rag_app(question)

    test_case = LLMTestCase(
        input=question,
        actual_output=result["answer"],
        retrieval_context=result["retrieved_chunks"],
    )

    for metric in [faithfulness_metric, answer_relevancy_metric]:
        metric.measure(test_case)
        status = "PASS" if metric.success else "FAIL"
        print(f"[{status}] {metric.__class__.__name__}: {metric.score:.3f}")

    failed = [m for m in [faithfulness_metric, answer_relevancy_metric] 
              if not m.success]
    if failed:
        names = ", ".join(m.__class__.__name__ for m in failed)
        raise AssertionError(f"Metrics below threshold: {names}")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run this with &lt;code&gt;pytest&lt;/code&gt;, and it either passes or fails like any other test. That's the whole point it turns a fuzzy "does the AI sound right" question into a binary CI/CD signal.&lt;/p&gt;

&lt;p&gt;The test suite includes retry logic to handle transient Gemini API 503 errors, automatically retrying up to 3 times with exponential backoff. DeepEval generates both JUnit XML and HTML reports, making it trivial to wire into any CI system that understands pytest output.&lt;/p&gt;

&lt;h2&gt;Load testing with k6 (and why you can't measure TTFT yet)&lt;/h2&gt;

&lt;p&gt;Here's where things get frustrating if you came here looking for a clean TTFT measurement story: &lt;strong&gt;the k6 SSE extension (&lt;code&gt;xk6-sse&lt;/code&gt;) is not compatible with k6 v2&lt;/strong&gt;. It targets &lt;code&gt;go.k6.io/k6 v1&lt;/code&gt;, and until it gets updated, you're stuck choosing between k6 v2's improved architecture or the ability to measure streaming metrics properly.&lt;/p&gt;

&lt;p&gt;So the companion repo does the pragmatic thing: it tests the &lt;code&gt;/chat/complete&lt;/code&gt; endpoint instead of the &lt;code&gt;/chat&lt;/code&gt; streaming endpoint, using k6's built-in &lt;code&gt;http&lt;/code&gt; module. No custom binary, no extensions, just standard k6. The tradeoff is you lose true TTFT measurement, because &lt;code&gt;/chat/complete&lt;/code&gt; waits for the full response before returning. What you get instead is end-to-end latency, which is still useful it tells you if the system is slow, just not &lt;em&gt;why&lt;/em&gt; it's slow.&lt;/p&gt;

&lt;p&gt;Here's what the test looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import http from 'k6/http';
import { Trend, Counter } from 'k6/metrics';
import { check } from 'k6';

const totalDuration = new Trend('total_duration_ms', true);
const tokensPerSecond = new Trend('tokens_per_second');

const BASE_URL = __ENV.RAG_APP_URL || 'http://localhost:8080';

export const options = {
  scenarios: {
    rag_chat: {
      executor: 'ramping-vus',
      stages: [
        { duration: '30s', target: 10 },
        { duration: '1m', target: 10 },
        { duration: '30s', target: 0 },
      ],
    },
  },
  thresholds: {
    http_req_duration: ['p(95)&amp;lt;6000'],
    total_duration_ms: ['p(95)&amp;lt;6000'],
  },
};

export default function () {
  const startTime = Date.now();

  const res = http.post(
    `${BASE_URL}/chat/complete`,
    JSON.stringify({ query: 'How do I run JMeter in non-GUI mode?' }),
    {
      headers: { 'Content-Type': 'application/json' },
      timeout: '30s',
    },
  );

  const duration = Date.now() - startTime;

  check(res, {
    'status 200': (r) =&amp;gt; r.status === 200,
    'has answer': (r) =&amp;gt; JSON.parse(r.body).answer !== undefined,
  });

  totalDuration.add(duration);

  // Rough tokens/sec estimate from word count
  const words = JSON.parse(res.body).answer.trim().split(/\s+/).length;
  tokensPerSecond.add((words / duration) * 1000);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The test ramps from 0 to 10 virtual users over 30 seconds, holds for a minute, then ramps back down. Thresholds are set at p95 &amp;lt; 6000ms for both &lt;code&gt;http_req_duration&lt;/code&gt; and the custom &lt;code&gt;total_duration_ms&lt;/code&gt; metric.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should you switch back to SSE?&lt;/strong&gt; Watch the xk6-sse repo. Once it adds k6 v2 support, swap the endpoint from &lt;code&gt;/chat/complete&lt;/code&gt; to &lt;code&gt;/chat&lt;/code&gt;, add the SSE extension to your Dockerfile, and you'll get true TTFT measurement. Until then, this is the most pragmatic path forward standard k6, no custom builds, just with the caveat that you're measuring end-to-end latency rather than streaming behavior.&lt;/p&gt;

&lt;p&gt;The companion repo includes both endpoints in the Express app so you can switch when you're ready:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Response&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /chat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SSE stream&lt;/td&gt;
&lt;td&gt;Ready for when xk6-sse supports k6 v2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /chat/complete&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full JSON&lt;/td&gt;
&lt;td&gt;Used by k6 and DeepEval today&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Wiring both gates into CI/CD&lt;/h2&gt;

&lt;p&gt;Once both tests run locally, wiring them into GitHub Actions is mostly plumbing: start the app, wait for it to be healthy, run the k6 gate, run the DeepEval gate, both in parallel since they're independent.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;name: RAG CI

on: [pull_request]

jobs:
  performance-gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Write app env file
        run: |
          cat &amp;gt; app/.env &amp;lt;&amp;lt; EOF
          GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }}
          GEMINI_MODEL=gemini-3.5-flash
          FILE_SEARCH_STORE_NAME=${{ secrets.FILE_SEARCH_STORE_NAME }}
          PORT=8080
          EOF

      - name: Start RAG app
        run: docker compose up -d --build app

      - name: Wait for health
        run: |
          timeout 60 bash -c 'until curl -f http://localhost:8080/health; do sleep 2; done'

      - name: Run k6 load test
        run: docker compose --profile perf run --rm k6

  quality-gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Write app env file
        run: |
          cat &amp;gt; app/.env &amp;lt;&amp;lt; EOF
          GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }}
          GEMINI_MODEL=gemini-3.5-flash
          FILE_SEARCH_STORE_NAME=${{ secrets.FILE_SEARCH_STORE_NAME }}
          PORT=8080
          EOF

      - name: Start RAG app
        run: docker compose up -d --build app

      - name: Wait for health
        run: |
          timeout 60 bash -c 'until curl -f http://localhost:8080/health; do sleep 2; done'

      - name: Run DeepEval tests
        env:
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
        run: docker compose --profile quality run --rm deepeval&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both jobs run on every pull request. A PR that slows down response time and a PR that quietly makes the model hallucinate get caught the same way, before either reaches a reviewer's eyeballs, let alone production.&lt;/p&gt;

&lt;p&gt;You'll need to add two secrets to your GitHub repo before the workflow will pass:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Secret&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your Gemini API key from https://aistudio.google.com/apikey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FILE_SEARCH_STORE_NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The store name from &lt;code&gt;setup-store.js&lt;/code&gt; (format: &lt;code&gt;fileSearchStores/your-store-id&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Setting SLOs&lt;/h2&gt;

&lt;p&gt;I'm deliberately not giving you one universal latency number to target. I've seen guidance ranging from sub-second targets for chat-style RAG apps to 3-5 second budgets for more complex document analysis, and the right number for you depends entirely on your retrieval backend, your model, and what your users are actually doing. Run the load test against your own baseline first, then set thresholds off that baseline, not off a number from a blog post (including this one).&lt;/p&gt;

&lt;p&gt;The example repo uses p95 &amp;lt; 6000ms as a starting point because that's what the test Gemini File Search RAG app achieves at 10 concurrent users with &lt;code&gt;gemini-3.5-flash&lt;/code&gt;. Your mileage will vary dramatically based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model choice (flash vs pro, size of context window actually used)&lt;/li&gt;



&lt;li&gt;Retrieval backend (vector DB query time, number of chunks retrieved)&lt;/li&gt;



&lt;li&gt;Document size and complexity&lt;/li&gt;



&lt;li&gt;Network latency to your LLM provider&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you should track regardless of the exact number:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;p95 and p99 latency, not just the median.&lt;/strong&gt; The tail experience is what users complain about.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Latency at your expected concurrency&lt;/strong&gt;, not at 1 user. RAG apps often degrade non-linearly under load because of retrieval bottlenecks.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Faithfulness and answer relevancy trending over time&lt;/strong&gt;, not just pass/fail on one run. A metric that's consistently 0.90 dropping to 0.78 is a signal even if both pass the 0.75 threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Wrap-up&lt;/h2&gt;

&lt;p&gt;RAG performance testing is really two disciplines wearing one trench coat: classic load testing with LLM-aware metrics, and LLM-as-judge quality scoring that classic load testing tools were never built to do. Run them both, gate on both, and you'll catch the regressions that a speed-only test walks right past.&lt;/p&gt;

&lt;p&gt;The current state of tooling isn't perfect you can't measure TTFT with k6 v2 without writing your own SSE client, and LLM-as-judge scoring has its own consistency quirks but it's good enough to catch regressions before production, which is the whole point of a CI/CD gate.&lt;/p&gt;

&lt;p&gt;Head to the &lt;a href="https://github.com/qainsights/rag-performance-testing-guide" rel="noopener noreferrer"&gt;companion GitHub repo&lt;/a&gt; for the full working app, k6 script, DeepEval tests, Docker Compose setup, and GitHub Actions workflow you can clone and run locally in under five minutes.&lt;/p&gt;

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

&lt;p&gt;Have you run into hallucination regressions that a pure load test missed? I'd like to hear how you caught them reply on X or open an issue on the companion repo.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>performance</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Qwen3 vs DeepSeek R1: Which Open-Source Reasoning Model Should You Use in 2026?</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Thu, 25 Jun 2026 15:11:58 +0000</pubDate>
      <link>https://dev.to/qainsights/qwen3-vs-deepseek-r1-which-open-source-reasoning-model-should-you-use-in-2026-370</link>
      <guid>https://dev.to/qainsights/qwen3-vs-deepseek-r1-which-open-source-reasoning-model-should-you-use-in-2026-370</guid>
      <description>&lt;p&gt;In this blog post, we will see how Qwen3 and DeepSeek R1 compare as open-source reasoning models, where each one shines, and which one you should actually run in 2026.&lt;/p&gt;

&lt;p&gt;Open-source reasoning models have changed the game. DeepSeek R1 felt like a revolution when it dropped in early 2025. Then Qwen3 from Alibaba quietly overtook Llama as the most downloaded model family on Hugging Face by late 2025. Now both are serious contenders.&lt;/p&gt;

&lt;p&gt;If you run local LLMs for code, automation, or performance analysis, you have probably stared at this choice. Let me break it down with one grounding example so you can make the call.&lt;/p&gt;

&lt;p&gt;DeepSeek R1 lit the fire for open-source reasoning. The distilled 14B and 32B variants are still excellent, especially for math-heavy tasks on limited hardware.&lt;/p&gt;

&lt;p&gt;But in 2026, Qwen3 is the more versatile daily driver. The hybrid thinking mode alone justifies the switch. You get DeepSeek-level depth when you need it and sub-5-second responses when you do not. The ecosystem, the model size range, and the tooling around Qwen3 are simply broader.&lt;/p&gt;

&lt;h3&gt;What Are These Models?&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DeepSeek R1&lt;/strong&gt; is a reasoning model from DeepSeek AI, released in January 2025. It uses a dense 671B parameter architecture trained with multi-stage reinforcement learning. Every single query goes through a chain-of-thought reasoning process. That is its identity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qwen3&lt;/strong&gt; is Alibaba's open-source LLM family, spanning 0.6B to 235B parameters. The flagship is Qwen3-235B-A22B, a Mixture-of-Experts (MoE) model that activates only 22B parameters per forward pass. Every Qwen3 model ships with a built-in dual-mode thinking system. Flip a soft switch in your prompt and the same model either engages deep chain-of-thought reasoning or returns fast responses like a traditional assistant.&lt;/p&gt;

&lt;p&gt;That single design decision separates the two philosophies.&lt;/p&gt;





&lt;h3&gt;The Key Architectural Difference&lt;/h3&gt;

&lt;p&gt;DeepSeek R1 is always reasoning. There is no off switch. Every query burns through a full chain-of-thought, whether you are asking it to fix a typo or solve a differential equation. Typical response latency for complex reasoning is 30 to 90 seconds. That is not viable for real-time customer-facing chat, but for batch processing, code review automation, or research tasks, it is acceptable.&lt;/p&gt;

&lt;p&gt;Qwen3 gives you a choice. Thinking mode on: deep reasoning, comparable to DeepSeek R1. Thinking mode off: fast response, like a traditional assistant.&lt;/p&gt;

&lt;p&gt;In Ollama, you trigger it simply:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ollama run qwen3:8b
/set think&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or prefix your prompt with &lt;code&gt;/think&lt;/code&gt; in API calls.&lt;/p&gt;

&lt;p&gt;This is a practical advantage. You do not always need a model to overthink. Qwen3 lets you decide.&lt;/p&gt;





&lt;h3&gt;A Simple Example: Performance Bottleneck Reasoning&lt;/h3&gt;

&lt;p&gt;Here is one concrete prompt to anchor the comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A load test has 100 virtual users hitting an API endpoint. Each request takes 2 seconds. What is the throughput in requests per second? Show your reasoning and flag any assumptions."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;DeepSeek R1&lt;/strong&gt; responded in approximately 95 seconds. It walked through Little's Law correctly: &lt;code&gt;Throughput = Concurrent Users / Response Time = 100 / 2 = 50 RPS&lt;/code&gt;. The answer was accurate. It also flagged that the formula assumes zero think time between requests, meaning 100% CPU utilization. Solid, but the wait was real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qwen3-8B with thinking mode&lt;/strong&gt; responded in about 105 seconds. Same correct answer. On output structuring, Qwen3 takes the lead. It added a note about how think time and pacing affect the real-world number, and formatted the output with clear sections. Slightly slower than DeepSeek on raw latency, but better organized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qwen3-8B without thinking mode&lt;/strong&gt; returned the correct answer in under 5 seconds. No chain-of-thought. Just: &lt;code&gt;50 RPS based on Throughput = Concurrent Users / Average Response Time&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a quick sanity check during a load test session, that 5-second response changes your workflow. For a deep architectural review where reasoning quality matters, both models land at the same level.&lt;/p&gt;

&lt;p&gt;The switchable thinking mode is the real differentiator in day-to-day use.&lt;/p&gt;





&lt;h3&gt;Benchmarks at a Glance&lt;/h3&gt;

&lt;p&gt;With only 60% activated and 35% total parameters, Qwen3-235B-A22B in thinking mode outperforms DeepSeek R1 on 17 out of 23 benchmarks, particularly on mathematics, agent tasks, and coding.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ArenaHard&lt;/strong&gt; (overall reasoning): Qwen3-235B scores 95.6, DeepSeek R1 scores 91.8&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;CodeForces Elo&lt;/strong&gt; (competitive programming): Qwen3-235B scores 2056, DeepSeek R1 scores 2029&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;MATH-500&lt;/strong&gt;: DeepSeek R1 scores 97.3, Qwen3 scores 97.2. Essentially tied.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DeepSeek R1 holds a clear advantage on pure mathematical reasoning. This is the benchmark where DeepSeek's reputation is most defensible. If your workload centers on mathematical reasoning, that edge is real.&lt;/p&gt;

&lt;p&gt;For coding specifically, Qwen3-32B in thinking mode scores 1970 on CodeForces Elo. That is above GPT-4o.&lt;/p&gt;





&lt;h3&gt;Hardware Requirements&lt;/h3&gt;

&lt;p&gt;This is where the gap becomes very practical.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DeepSeek R1 full model&lt;/strong&gt;: 671B parameters, needs 400+ GB memory. Not viable on consumer hardware.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;DeepSeek R1 distilled (14B)&lt;/strong&gt;: Runs on a 12 GB GPU, strong reasoning performance.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Qwen3-8B&lt;/strong&gt;: Runs on 6 GB VRAM in Q4 quantization. RTX 3060 level.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Qwen3-32B&lt;/strong&gt;: Runs on a single RTX 4090 with 24 GB VRAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qwen3-4B and Qwen3-8B are ideal for edge use, requiring only 6 to 12 GB of VRAM post-quantization.&lt;/p&gt;

&lt;p&gt;That means Qwen3-8B runs on a MacBook Air M2 with 8 GB unified memory. DeepSeek R1 distills are the practical comparison here, not the full 671B model.&lt;/p&gt;





&lt;h3&gt;Licensing&lt;/h3&gt;

&lt;p&gt;Both are open source, but with different terms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DeepSeek R1&lt;/strong&gt;: MIT License. No thresholds, no restrictions. Commercial use, fine-tuning, and redistribution are fully open.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Qwen3&lt;/strong&gt;: Apache 2.0 for models up to 35B parameters. If you use a larger Qwen model and reach 100 million monthly active users, Alibaba requires a separate commercial agreement. For smaller Qwen models, Apache 2.0 applies cleanly with no threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most teams, this distinction does not matter. Both are practically free to use.&lt;/p&gt;





&lt;h3&gt;When to Use Which&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use DeepSeek R1 distills when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your workload is purely math or formal logic&lt;/li&gt;



&lt;li&gt;You want the MIT license with zero usage thresholds&lt;/li&gt;



&lt;li&gt;You are fine with always-on reasoning latency and do not need a fast path&lt;/li&gt;



&lt;li&gt;You have a 12 to 24 GB GPU and want specialized reasoning performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Qwen3 when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to switch between fast responses and deep reasoning based on the task&lt;/li&gt;



&lt;li&gt;You want a model family that scales from 0.6B on edge devices up to 235B&lt;/li&gt;



&lt;li&gt;You are building agents with tool use (the Qwen-Agent framework makes this clean)&lt;/li&gt;



&lt;li&gt;You need strong multilingual support. Qwen3 covers 119 languages; DeepSeek covers roughly 30.&lt;/li&gt;



&lt;li&gt;Code quality and output structure matter to you&lt;/li&gt;
&lt;/ul&gt;





&lt;h3&gt;Final Verdict&lt;/h3&gt;

&lt;p&gt;DeepSeek R1 lit the fire for open-source reasoning. The distilled 14B and 32B variants are still excellent, especially for math-heavy tasks on limited hardware.&lt;/p&gt;

&lt;p&gt;But in 2026, Qwen3 is the more versatile daily driver. The hybrid thinking mode alone justifies the switch. You get DeepSeek-level depth when you need it and sub-5-second responses when you do not. The ecosystem, the model size range, and the tooling around Qwen3 are simply broader.&lt;/p&gt;

&lt;p&gt;I currently run Qwen3-8B locally for quick analysis tasks and Qwen3-32B for anything that needs actual reasoning. For pure math puzzles, I still reach for an R1 distill.&lt;/p&gt;

&lt;p&gt;Which one are you running on your local setup? Are you using thinking mode, or keeping it off by default? Let me know in the comments.&lt;/p&gt;

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

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
    </item>
    <item>
      <title>Codex CLI vs Claude Code: A Deep-Dive Command Comparison</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Wed, 24 Jun 2026 14:50:03 +0000</pubDate>
      <link>https://dev.to/qainsights/codex-cli-vs-claude-code-a-deep-dive-command-comparison-1i12</link>
      <guid>https://dev.to/qainsights/codex-cli-vs-claude-code-a-deep-dive-command-comparison-1i12</guid>
      <description>&lt;p&gt;In this blog post, we will see how the two most talked-about AI coding CLIs, OpenAI's Codex CLI and Anthropic's Claude Code, stack up command by command. Not just the headline features, but the small wins, the gaps, the uncommon flags, and the places where one clearly pulls ahead. Everything here is sourced directly from the official docs.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Codex CLI vs Claude Code CLI commands: what's the difference?&lt;/strong&gt;Both are agentic terminal coding tools, but their command surfaces diverge significantly.If you need deep CI integration and multi-agent pipelines, choose Claude Code. If you need local models or a richer TUI experience, choose Codex CLI.&lt;/p&gt;


&lt;h2&gt;Quick Context&lt;/h2&gt;

&lt;p&gt;Both tools are agentic coding CLIs that live in your terminal. They read codebases, edit files, run shell commands, and talk to external services over MCP. The underlying models are different (Claude for Anthropic, GPT-family for OpenAI), but architecturally they are solving the same problem.&lt;/p&gt;

&lt;p&gt;I have been using Claude Code daily as part of my performance engineering work and plugin development. I recently started exploring Codex CLI seriously after OpenAI formalized its docs under developers.openai.com. This post is the comparison I wish I had when I started.&lt;/p&gt;





&lt;h2&gt;Installation at a Glance&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude Code:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;npm install -g @anthropic-ai/claude-code
claude auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Codex CLI:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# macOS / Linux
curl -fsSL https://chatgpt.com/codex/install.sh | sh

# Or via npm
npm i -g @openai/codex

codex login
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both need Node.js. Claude Code requires an Anthropic account (Claude subscription or API key). Codex CLI authenticates via ChatGPT OAuth or an OpenAI API key.&lt;/p&gt;





&lt;h2&gt;Core Commands Side by Side&lt;/h2&gt;

&lt;p&gt;Here are the foundational commands every developer uses daily.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Codex CLI&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Start interactive session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start with initial prompt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude "explain this project"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex "explain this project"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-interactive one-shot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude -p "query"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;codex exec "query"&lt;/code&gt; (alias: &lt;code&gt;codex e&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipe content&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat logs.txt | claude -p "explain"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex exec - &amp;lt; logs.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continue last session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude -c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex resume --last&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resume by name/ID&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude -r "auth-refactor" "query"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex resume &amp;lt;SESSION_ID&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update CLI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude update&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex update&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth login&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude auth login&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex login&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth logout&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude auth logout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex logout&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude auth status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex login status&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configure MCP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude mcp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex mcp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manage plugins&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude plugin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex plugin marketplace&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fork a session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;claude --fork-session --resume &amp;lt;id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codex fork&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both tools have non-interactive modes perfect for CI pipelines. Claude Code uses &lt;code&gt;-p&lt;/code&gt; (print mode). Codex CLI uses &lt;code&gt;exec&lt;/code&gt; as a proper subcommand with its own flag surface.&lt;/p&gt;





&lt;h2&gt;Commands Only in Claude Code&lt;/h2&gt;

&lt;p&gt;Claude Code has a significantly deeper command surface for background agent management. These are commands with no Codex equivalent.&lt;/p&gt;

&lt;h3&gt;Background Agent Management&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Start as a background agent and return to prompt immediately
claude --bg "investigate the flaky test"

# Attach to a background session
claude attach 7c5dcf5d

# See logs from a background session
claude logs 7c5dcf5d

# Stop a background session
claude stop 7c5dcf5d

# Restart a background session (picks up updated binary)
claude respawn 7c5dcf5d

# Remove from the list (transcript stays on disk)
claude rm 7c5dcf5d
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the biggest functional gap in Codex right now. Claude Code has a full background session supervisor with &lt;code&gt;claude daemon status&lt;/code&gt; and &lt;code&gt;claude daemon stop --any&lt;/code&gt;. You can run multiple agents in parallel, attach and detach, and inspect each session's recent output with &lt;code&gt;claude logs&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Daemon Management&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Check the background supervisor's state
claude daemon status

# Stop the supervisor (keep workers running to reconnect later)
claude daemon stop --any --keep-workers
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Project State Management&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Preview what would be deleted
claude project purge ~/work/repo --dry-run

# Delete all local Claude Code state for a project
claude project purge ~/work/repo -y
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This cleans up transcripts, task lists, debug logs, file-edit history, and prompt history. Useful when onboarding a project fresh or cleaning up stale state.&lt;/p&gt;

&lt;h3&gt;Ultrareview&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Run ultrareview on a PR non-interactively
claude ultrareview 1234 --json
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Codex does have a &lt;code&gt;/review&lt;/code&gt; slash command inside sessions, but &lt;code&gt;claude ultrareview&lt;/code&gt; is a standalone CI-friendly command that exits with 0 on success and 1 on failure.&lt;/p&gt;

&lt;h3&gt;Remote Control&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Start a remote control server so you can control Claude Code from claude.ai
claude remote-control --name "My Project"

# Or start an interactive session with remote control enabled
claude --remote-control "My Project"

# Resume a web session in your local terminal
claude --teleport
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a genuinely unique capability. You start a session locally, expose it over Remote Control, and then control it from claude.ai or the mobile Claude app. No Codex equivalent exists.&lt;/p&gt;

&lt;h3&gt;Long-Lived Token for CI&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Generate a long-lived OAuth token for CI pipelines
claude setup-token
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Codex uses a different CI flow (piping API key via stdin with &lt;code&gt;codex login --with-api-key&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;Install Specific Version&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;claude install 2.1.118
claude install stable
claude install latest
&lt;/code&gt;&lt;/pre&gt;





&lt;h2&gt;Commands Only in Codex CLI&lt;/h2&gt;

&lt;h3&gt;Cloud Task Management&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Browse cloud tasks from the terminal
codex cloud

# Submit a cloud task directly
codex cloud exec --env ENV_ID "fix the auth bug"

# List recent tasks with JSON output
codex cloud list --json --limit 10

# Apply a cloud task diff to your local working tree
codex apply TASK_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is Codex's hybrid cloud-plus-local model. You can kick off tasks in the Codex cloud environment and then &lt;code&gt;codex apply&lt;/code&gt; their diffs locally. Claude Code has remote web sessions but not this apply-a-cloud-diff pattern.&lt;/p&gt;

&lt;h3&gt;Sandbox Helper&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Run a command inside Codex's sandboxing layer (macOS Seatbelt)
codex sandbox --permissions-profile my-profile -- pytest tests/

# Log sandbox denials for debugging
codex sandbox --log-denials -- npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can test what commands Codex allows or denies before committing a config. Very useful for security-conscious teams.&lt;/p&gt;

&lt;h3&gt;Exec Policy Testing&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Check whether a command would be allowed, prompted, or blocked
codex execpolicy --rules ~/.codex/rules/my-policy.rules --pretty -- git push

# Validate rules before saving them
codex execpolicy -r policy.rules -r another.rules -- rm -rf /tmp/junk
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a preview feature that lets you unit-test your execution policy files. Nothing like this exists in Claude Code.&lt;/p&gt;

&lt;h3&gt;Shell Completion Scripts&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Generate completions for Zsh
codex completion zsh &amp;gt; "${fpath[1]}/_codex"

# Generate for Bash, Fish, PowerShell, Elvish
codex completion bash
codex completion fish
codex completion power-shell
codex completion elvish
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Claude Code does not have a &lt;code&gt;completion&lt;/code&gt; command. You get whatever your shell discovers from the binary.&lt;/p&gt;

&lt;h3&gt;Feature Flag Management&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# List all feature flags with maturity and current state
codex features list

# Persistently enable a feature
codex features enable subagents

# Persistently disable a feature
codex features disable experimental-network
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Claude Code exposes betas via &lt;code&gt;--betas&lt;/code&gt; but does not have a persistent feature flag manager as a first-class CLI command.&lt;/p&gt;

&lt;h3&gt;Debug Model Catalog&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Print the raw model catalog Codex sees
codex debug models

# Show only the bundled catalog (no remote refresh)
codex debug models --bundled
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Useful when troubleshooting model availability or provider routing issues.&lt;/p&gt;

&lt;h3&gt;Run Codex as an MCP Server&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Expose Codex itself as an MCP tool for other agents to consume
codex mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a powerful composition pattern. Another agentic tool (including Claude Code) can talk to Codex over MCP. I have not seen Claude Code offer an equivalent &lt;code&gt;claude mcp-server&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;Launch Desktop App from CLI&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Open Codex Desktop app, pointing at a workspace
codex app ~/work/my-project
&lt;/code&gt;&lt;/pre&gt;





&lt;h2&gt;Flags Compared&lt;/h2&gt;

&lt;h3&gt;Shared Flags (Different Names)&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Codex CLI&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model selection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--model claude-sonnet-4-6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--model gpt-4.1&lt;/code&gt; / &lt;code&gt;-m gpt-5.4&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extra directories&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--add-dir ../lib&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--add-dir ../lib&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-interactive&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--print&lt;/code&gt; / &lt;code&gt;-p&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--json&lt;/code&gt; on &lt;code&gt;exec&lt;/code&gt; subcommand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skip permissions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--dangerously-skip-permissions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--dangerously-bypass-approvals-and-sandbox&lt;/code&gt; / &lt;code&gt;--yolo&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output format&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--output-format json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--json&lt;/code&gt; on exec&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;Flags Only in Claude Code&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Run with minimal setup (no hooks, skills, MCP, CLAUDE.md)
claude --bare -p "query"

# Set reasoning effort
claude --effort high
claude --effort max

# Append to system prompt without replacing it
claude --append-system-prompt "Always use TypeScript"
claude --append-system-prompt-file ./style-rules.txt

# Validated JSON output matching a JSON Schema
claude -p --json-schema '{"type":"object"}' "query"

# Budget cap for API-billed sessions
claude -p --max-budget-usd 5.00 "query"

# Limit agentic turns
claude -p --max-turns 3 "query"

# Auto-connect to IDE on startup
claude --ide

# Spin up an isolated git worktree
claude -w feature-auth
claude -w feature-auth --tmux

# Resume from a PR number
claude --from-pr 123

# Select a fallback model chain
claude --fallback-model sonnet,haiku

# Screen reader accessible output
claude --ax-screen-reader

# Improve prompt cache reuse across CI runs
claude -p --exclude-dynamic-system-prompt-sections "query"

# Set session display name
claude -n "my-feature-work"

# Load plugin for session only
claude --plugin-dir ./my-plugin
claude --plugin-url https://example.com/plugin.zip

# Disable all slash commands and skills
claude --disable-slash-commands

# Start in safe mode (all customizations disabled)
claude --safe-mode

# Define subagents inline
claude --agents '{"reviewer":{"description":"Reviews code","prompt":"You are a code reviewer"}}'

# Enable advisor tool with a specific model
claude --advisor opus

# Start as a background agent immediately
claude --bg "investigate the flaky test"

# Run a shell command as a PTY-backed background job
claude --bg --exec 'pytest -x'

# Teammate display mode
claude --teammate-mode tmux

# Permission mode
claude --permission-mode plan
claude --permission-mode auto
claude --permission-mode acceptEdits
claude --permission-mode bypassPermissions

# Chrome browser integration
claude --chrome
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Flags Only in Codex CLI&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Use local Ollama model
codex --oss

# Switch approval behavior
codex --ask-for-approval on-request

# Attach images to the initial prompt
codex --image screenshot.png "why is this broken?"
codex -i wireframe.png,design.png "implement this"

# Load a named config profile
codex --profile ci

# Enable live web search
codex --search

# Select sandbox policy
codex --sandbox workspace-write

# Connect TUI to a remote app-server
codex --remote ws://192.168.1.10:8080

# Set working directory for the agent
codex --cd /path/to/project "run tests"

# Override a config value inline
codex -c model=gpt-4.1 "query"
codex -c features.subagents=true "query"

# Disable alternate TUI screen
codex --no-alt-screen
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;--oss&lt;/code&gt; flag is a genuine differentiator. Codex CLI supports pointing at a local Ollama instance for offline or privacy-sensitive work. Claude Code does not have this.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--image&lt;/code&gt; / &lt;code&gt;-i&lt;/code&gt; flag at the global level is very ergonomic. In Claude Code, you can reference images inside sessions, but it is not a global flag on the CLI launch itself.&lt;/p&gt;





&lt;h2&gt;Slash Commands Face-off&lt;/h2&gt;

&lt;p&gt;Both tools have in-session slash commands. Here is how the key ones map.&lt;/p&gt;

&lt;h3&gt;Present in Both (Similar Purpose)&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Codex CLI&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model switching&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/model&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compact context&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/compact&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/compact&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New conversation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/new&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/new&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resume session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/resume&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/resume&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fork conversation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/fork&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/fork&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/quit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/quit&lt;/code&gt;, &lt;code&gt;/exit&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Init project file&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/init&lt;/code&gt; (CLAUDE.md)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/init&lt;/code&gt; (AGENTS.md)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP tools&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/mcp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/mcp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session status&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/context&lt;/code&gt;, &lt;code&gt;/cost&lt;/code&gt;, &lt;code&gt;/stats&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/status&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;Slash Commands Only in Claude Code&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;/compact "Focus on the auth module and current test failures"
/output-style Explanatory
/output-style my-custom-style
/insights           # compiles past month of usage into an HTML report
/add-dir ../lib     # add working directory mid-session
/rename             # rename the current session
/export             # export conversation as plain text
/terminal-setup     # activate keyboard shortcuts for your terminal
/cost               # how much have I spent? (API users)
/stats              # how much have I used? (Pro/Max users)
/extra-usage        # configure what happens when you hit rate limit
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;/insights&lt;/code&gt; command is genuinely impressive. It reads your last month of usage history and compiles it into a detailed HTML report. I have not found anything like it in Codex.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/output-style&lt;/code&gt; system lets you define named styles in &lt;code&gt;.claude/commands/&lt;/code&gt; and switch between them. This is a powerful content-shaping tool for teams.&lt;/p&gt;

&lt;h3&gt;Slash Commands Only in Codex CLI&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;/goal "Finish the migration and keep tests green"  # set a persistent task goal
/goal pause        # pause the goal tracking
/goal resume       # resume it
/personality pragmatic  # set communication style (friendly/pragmatic/none)
/fast on           # toggle Fast service tier
/plan              # switch to plan mode
/side "is there an obvious risk here?"  # start an ephemeral side conversation
/btw "quick thought"   # alias for /side
/approve           # approve a denied auto-review action and retry
/memories          # configure memory injection and generation
/skills            # browse and use skills
/apps              # browse connectors and insert into prompt
/plugins           # browse installed/discoverable plugins
/hooks             # view and manage lifecycle hooks
/archive           # archive session and exit
/delete            # permanently delete session and exit
/copy              # copy latest response to clipboard (Ctrl+O also works)
/diff              # show Git diff including untracked files
/experimental      # toggle experimental features persistently
/vim               # toggle Vim mode for the composer
/keymap            # remap TUI keyboard shortcuts
/raw               # toggle raw scrollback mode
/review            # ask Codex to review your working tree
/ps                # show background terminals and recent output
/stop              # stop all background terminals
/debug-config      # print config layer diagnostics
/statusline        # configure TUI footer items interactively
/title             # configure terminal window/tab title items
/theme             # choose a syntax-highlighting theme
/permissions       # adjust approval policy mid-session
/ide               # pull IDE context (open files, selection) into prompt
/usage daily       # show daily token usage
/usage weekly
/usage cumulative
/feedback          # send diagnostics to OpenAI
/import            # import Claude Code setup into Codex
/sandbox-add-read-dir C:\path  # grant sandbox read access (Windows only)
/agent             # switch active agent thread
/goal              # persistent task goal tracking
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;/side&lt;/code&gt; command is something I wish Claude Code had. You can start an ephemeral side conversation to ask a quick focused question without polluting the main thread's transcript. You type &lt;code&gt;/side "check if this plan has an obvious flaw"&lt;/code&gt;, get your answer, and return to the main task. Brilliant.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/goal&lt;/code&gt; command gives Codex persistent objective tracking during long-running tasks. You set a goal and the agent keeps it in view across multiple turns.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/personality&lt;/code&gt; command lets you shift Codex's communication style between &lt;code&gt;friendly&lt;/code&gt;, &lt;code&gt;pragmatic&lt;/code&gt;, and &lt;code&gt;none&lt;/code&gt; without changing your instructions. Small win, but very practical when switching between debugging and documentation tasks.&lt;/p&gt;





&lt;h2&gt;Uncommon Commands Worth Knowing&lt;/h2&gt;

&lt;p&gt;These are the commands that most people miss but deliver real value once you discover them.&lt;/p&gt;

&lt;h3&gt;Claude Code: &lt;code&gt;--exclude-dynamic-system-prompt-sections&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;claude -p --exclude-dynamic-system-prompt-sections "run the test suite"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This moves per-machine dynamic sections (working directory, environment info, memory paths) into the first user message instead of the system prompt. The result is better prompt cache reuse across different users and machines running the same task. Essential for teams running Claude Code in shared CI environments.&lt;/p&gt;

&lt;h3&gt;Claude Code: &lt;code&gt;--bare&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;claude --bare -p "explain this function"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Skips auto-discovery of hooks, skills, plugins, MCP servers, auto memory, and CLAUDE.md. Sessions start significantly faster. Useful for quick scripted calls where you do not need any project configuration.&lt;/p&gt;

&lt;h3&gt;Claude Code: &lt;code&gt;--from-pr&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;claude --from-pr 123
claude --from-pr https://github.com/owner/repo/pull/123
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Resumes sessions linked to a specific pull request. Sessions get linked automatically when Claude creates the PR. Supports GitHub, GitHub Enterprise, GitLab, and Bitbucket URLs.&lt;/p&gt;

&lt;h3&gt;Claude Code: &lt;code&gt;--fallback-model&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;claude --fallback-model sonnet,haiku -p "query"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Automatic fallback when the primary model is overloaded or unavailable. Accepts a comma-separated list tried in order. You can persist a chain via the &lt;code&gt;fallbackModel&lt;/code&gt; setting.&lt;/p&gt;

&lt;h3&gt;Codex CLI: &lt;code&gt;codex execpolicy&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;codex execpolicy --rules ~/.codex/rules/production.rules --pretty -- git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A policy dry-run. You pass your &lt;code&gt;.rules&lt;/code&gt; files and a command, and Codex tells you whether it would allow, prompt, or block that command. This is a fantastic tool for validating security policy before deploying to CI.&lt;/p&gt;

&lt;h3&gt;Codex CLI: &lt;code&gt;--oss&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;codex --oss "refactor this module"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Points Codex at a locally running Ollama instance. No API calls, no data leaving your machine. Validates that Ollama is running before starting.&lt;/p&gt;

&lt;h3&gt;Codex CLI: &lt;code&gt;codex apply&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;codex apply TASK_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Applies the latest diff from a Codex cloud task to your local working tree. The workflow is: run a task in the cloud environment, review the result on the web, then pull the diff locally with one command. Performance engineers who run long test analysis tasks in cloud environments will appreciate this.&lt;/p&gt;

&lt;h3&gt;Codex CLI: &lt;code&gt;/side&lt;/code&gt; and &lt;code&gt;/btw&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;/side "does this API response shape match our schema?"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An ephemeral fork of the current conversation. The side thread has its own transcript. The parent thread's status stays visible in the TUI while you are in side mode. Type your quick question, get the answer, return. This is a quality-of-life feature I would happily see in Claude Code.&lt;/p&gt;

&lt;h3&gt;Claude Code: &lt;code&gt;claude ultrareview&lt;/code&gt;
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;claude ultrareview 1234 --json --timeout 60
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Runs a deep code review non-interactively. Prints findings to stdout and exits 0 on success or 1 on failure. Pipe it into your CI gate.&lt;/p&gt;





&lt;h2&gt;Small Wins: Category by Category&lt;/h2&gt;

&lt;h3&gt;Session Management: Claude Code Wins&lt;/h3&gt;

&lt;p&gt;Claude Code has a richer session management surface. Background agents with a daemon supervisor, &lt;code&gt;claude logs&lt;/code&gt;, &lt;code&gt;claude attach&lt;/code&gt;, &lt;code&gt;claude respawn&lt;/code&gt;, &lt;code&gt;claude rm&lt;/code&gt;, and the &lt;code&gt;claude agents&lt;/code&gt; view for monitoring and dispatching parallel sessions. Codex has &lt;code&gt;codex resume&lt;/code&gt; and &lt;code&gt;codex fork&lt;/code&gt;, which cover the basics but stop there.&lt;/p&gt;

&lt;h3&gt;Sandbox Control: Codex CLI Wins&lt;/h3&gt;

&lt;p&gt;Codex's sandbox story is more explicit. You choose &lt;code&gt;read-only&lt;/code&gt;, &lt;code&gt;workspace-write&lt;/code&gt;, or &lt;code&gt;danger-full-access&lt;/code&gt; at the flag level. The &lt;code&gt;codex sandbox&lt;/code&gt; command lets you run arbitrary commands inside Codex's sandbox layer to test policies. The &lt;code&gt;codex execpolicy&lt;/code&gt; command lets you validate rules before saving them. Claude Code has permission modes (&lt;code&gt;plan&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;acceptEdits&lt;/code&gt;, &lt;code&gt;bypassPermissions&lt;/code&gt;) but does not expose the underlying sandbox policy as a testable surface.&lt;/p&gt;

&lt;h3&gt;Image Input: Codex CLI Small Win&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;codex --image ui-screenshot.png "why is this button misaligned?"
codex -i wireframe.png,mockup.png "implement this layout"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Codex CLI accepts images as a global flag at session launch. You can attach multiple images with a comma-separated list. Claude Code supports image input inside sessions (drag and drop in the TUI or pasting), but &lt;code&gt;--image&lt;/code&gt; is not a CLI launch flag.&lt;/p&gt;

&lt;h3&gt;CI Scripting: Claude Code Wins&lt;/h3&gt;

&lt;p&gt;Claude Code has more CI-specific flags: &lt;code&gt;--max-budget-usd&lt;/code&gt; caps API spend, &lt;code&gt;--max-turns&lt;/code&gt; limits agentic turns, &lt;code&gt;--no-session-persistence&lt;/code&gt; avoids writing to disk, &lt;code&gt;--output-format stream-json&lt;/code&gt; gives structured streaming output, &lt;code&gt;--include-hook-events&lt;/code&gt; and &lt;code&gt;--include-partial-messages&lt;/code&gt; allow fine-grained pipeline observability. The &lt;code&gt;claude setup-token&lt;/code&gt; command generates long-lived OAuth tokens for CI authentication without a browser.&lt;/p&gt;

&lt;p&gt;Codex has &lt;code&gt;codex exec --ephemeral&lt;/code&gt; to skip session persistence and &lt;code&gt;codex exec --output-last-message&lt;/code&gt; to write the final response to a file, which is handy in GitHub Action pipelines.&lt;/p&gt;

&lt;h3&gt;Local Model Support: Codex CLI Wins&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;codex --oss&lt;/code&gt; with Ollama support is a genuine differentiator. If you work in an air-gapped or privacy-sensitive environment, Codex CLI has a path. Claude Code currently has no equivalent.&lt;/p&gt;

&lt;h3&gt;Context Management: Claude Code Wins Slightly&lt;/h3&gt;

&lt;p&gt;Claude Code's &lt;code&gt;/compact&lt;/code&gt; accepts focus instructions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/compact Focus on the auth module and current test failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Codex's &lt;code&gt;/compact&lt;/code&gt; summarizes the conversation without focus parameters. Also, Claude Code's &lt;code&gt;/insights&lt;/code&gt; command compiling a usage HTML report has no Codex equivalent.&lt;/p&gt;

&lt;h3&gt;Plugin Architecture: Codex CLI More Explicit&lt;/h3&gt;

&lt;p&gt;Codex has a proper &lt;code&gt;codex plugin marketplace&lt;/code&gt; command for managing plugin marketplace sources from Git repos or local directories. You can pin refs and use sparse checkouts. Claude Code has &lt;code&gt;claude plugin install&lt;/code&gt; against a marketplace, but the marketplace management surface is thinner at the CLI level.&lt;/p&gt;

&lt;h3&gt;Remote Work: Both Have Unique Angles&lt;/h3&gt;

&lt;p&gt;Claude Code has &lt;code&gt;claude remote-control&lt;/code&gt;, which lets you control a local terminal session from claude.ai or the mobile app. Codex CLI has &lt;code&gt;--remote ws://host:port&lt;/code&gt;, which connects a local TUI to a remote &lt;code&gt;codex app-server&lt;/code&gt;. Different models of remote work, both useful depending on your setup.&lt;/p&gt;





&lt;h2&gt;What Is Missing in Each Tool&lt;/h2&gt;

&lt;h3&gt;Missing in Claude Code&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;codex --oss&lt;/code&gt; style local model support (Ollama)&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;codex completion&lt;/code&gt; for shell completion scripts&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;codex execpolicy&lt;/code&gt; for policy dry-runs&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;codex sandbox&lt;/code&gt; for testing sandbox behavior&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;codex cloud&lt;/code&gt; and &lt;code&gt;codex apply&lt;/code&gt; for cloud task management&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/side&lt;/code&gt; for ephemeral side conversations&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/goal&lt;/code&gt; for persistent task objective tracking&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/personality&lt;/code&gt; for communication style control&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/fast&lt;/code&gt; for service tier switching&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/diff&lt;/code&gt; as a slash command (Claude Code does have git awareness, but not as a quick slash command)&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/keymap&lt;/code&gt; for interactive keyboard remapping&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/theme&lt;/code&gt; for syntax highlighting selection&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt; and &lt;code&gt;/title&lt;/code&gt; for TUI customization&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--image&lt;/code&gt; as a launch-time CLI flag&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/approve&lt;/code&gt; for retrying auto-review denials&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;codex features&lt;/code&gt; for persistent feature flag management&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;codex debug models&lt;/code&gt; to inspect model catalog&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Missing in Codex CLI&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Background session management at the daemon level (&lt;code&gt;claude daemon&lt;/code&gt;, &lt;code&gt;claude attach&lt;/code&gt;, &lt;code&gt;claude logs&lt;/code&gt;, &lt;code&gt;claude respawn&lt;/code&gt;)&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude ultrareview&lt;/code&gt; as a standalone CI command&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude remote-control&lt;/code&gt; to control terminal sessions from the web/mobile app&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude --teleport&lt;/code&gt; to bring a web session back to the local terminal&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude --from-pr&lt;/code&gt; to resume sessions linked to a specific PR&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude setup-token&lt;/code&gt; for long-lived CI tokens&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude project purge&lt;/code&gt; for clean project state management&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude --worktree&lt;/code&gt; and &lt;code&gt;--tmux&lt;/code&gt; for isolated git worktrees&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;claude --advisor&lt;/code&gt; for the server-side advisor tool&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--effort&lt;/code&gt; levels (low/medium/high/xhigh/max)&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--fallback-model&lt;/code&gt; chains&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--bare&lt;/code&gt; for minimal fast-start scripted sessions&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--exclude-dynamic-system-prompt-sections&lt;/code&gt; for prompt cache optimization&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--json-schema&lt;/code&gt; for validated structured output&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;--max-budget-usd&lt;/code&gt; for spend caps&lt;/li&gt;



&lt;li&gt;System prompt control flags (&lt;code&gt;--system-prompt&lt;/code&gt;, &lt;code&gt;--system-prompt-file&lt;/code&gt;, &lt;code&gt;--append-system-prompt&lt;/code&gt;, &lt;code&gt;--append-system-prompt-file&lt;/code&gt;)&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/insights&lt;/code&gt; usage history report&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/output-style&lt;/code&gt; named output personas&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt; for session naming mid-session&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt; conversation to plain text&lt;/li&gt;



&lt;li&gt;Custom commands via &lt;code&gt;.claude/commands/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;





&lt;p&gt;&lt;strong&gt;What is the difference between Codex CLI and Claude Code?&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Both are AI-powered terminal coding agents. Claude Code is built by Anthropic and runs Claude models. Codex CLI is built by OpenAI and runs GPT-family models. They share core interactive and non-interactive modes but differ significantly in background agent management, sandbox control, CI flags, and TUI features.&lt;/p&gt;  &lt;strong&gt;Does Codex CLI support local models?&lt;/strong&gt; &lt;p&gt;Yes. Codex CLI supports local Ollama models via the --oss flag. This runs the agent without any API calls. Claude Code does not have an equivalent local model flag.&lt;/p&gt;  &lt;strong&gt;Does Claude Code support background agents?&lt;/strong&gt; &lt;p&gt;Yes. Claude Code has a full background agent system with claude --bg, claude attach, claude logs, claude respawn, claude rm, and a daemon supervisor managed via claude daemon status and claude daemon stop. Codex CLI does not have an equivalent daemon-managed background session infrastructure.&lt;/p&gt;  &lt;strong&gt;Which CLI is better for CI pipelines?&lt;/strong&gt; &lt;p&gt;Claude Code has more CI-focused flags including --max-budget-usd for spend caps, --max-turns to limit agentic turns, --no-session-persistence, --json-schema for validated structured output, and claude setup-token for long-lived OAuth tokens. Codex CLI offers codex exec with --ephemeral and --output-last-message, and a native GitHub Action.&lt;/p&gt;  &lt;strong&gt;What commands are missing in Codex CLI compared to Claude Code?&lt;/strong&gt; &lt;p&gt;Codex CLI is missing background session management (claude daemon, claude attach, claude logs), claude ultrareview for CI code review, claude remote-control for web and mobile session control, --from-pr to resume sessions linked to a PR, --worktree for isolated git worktrees, --fallback-model chains, --max-budget-usd spend caps, and the /insights slash command.&lt;/p&gt;  &lt;strong&gt;What commands are missing in Claude Code compared to Codex CLI?&lt;/strong&gt; &lt;p&gt;Claude Code is missing local model support via Ollama, codex completion for shell completion scripts, codex execpolicy for sandbox policy dry-runs, the /side slash command for ephemeral side conversations, /goal for persistent task objective tracking, /personality for communication style switching, /theme for syntax highlighting, and --image as a launch-time flag.&lt;/p&gt;  

&lt;h2&gt;My Take&lt;/h2&gt;

&lt;p&gt;Both tools are genuinely capable. My honest observation after going through every documented command:&lt;/p&gt;

&lt;p&gt;Claude Code has a deeper background agent infrastructure. If you are building multi-agent pipelines, running parallel workloads, or need tight CI integration with structured outputs, Claude Code's flag surface and daemon management are hard to beat.&lt;/p&gt;

&lt;p&gt;Codex CLI wins on local model flexibility, sandbox policy control, and the TUI experience. The &lt;code&gt;/side&lt;/code&gt; command, &lt;code&gt;/goal&lt;/code&gt; tracking, and &lt;code&gt;/personality&lt;/code&gt; switching feel like thoughtful UX investments. The &lt;code&gt;codex execpolicy&lt;/code&gt; command for policy dry-runs shows a security-first mindset.&lt;/p&gt;

&lt;p&gt;What I personally want to see: Claude Code adopt &lt;code&gt;--image&lt;/code&gt; as a launch flag and a &lt;code&gt;/side&lt;/code&gt; equivalent. Codex CLI needs a proper background daemon for parallel agents and a &lt;code&gt;--max-budget-usd&lt;/code&gt; style spend cap for CI use.&lt;/p&gt;

&lt;p&gt;Pick your tool based on your model preference first, then your workflow. If you need remote session control or deep CI scripting, lean Claude Code. If you need local model support or prefer a more granular TUI, lean Codex CLI.&lt;/p&gt;

&lt;p&gt;Have you switched between both tools on the same project? I would love to know which commands you reach for first. Drop a comment below.&lt;/p&gt;

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





</description>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Toy Story: The Open-Source Ecosystem</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Fri, 19 Jun 2026 16:41:20 +0000</pubDate>
      <link>https://dev.to/qainsights/toy-story-the-open-source-ecosystem-24ia</link>
      <guid>https://dev.to/qainsights/toy-story-the-open-source-ecosystem-24ia</guid>
      <description>&lt;p&gt;As schools are off and Toy Story 5 is just around the corner, we started binge-watching Toy Story from 1 to 4. While watching, suddenly this idea popped up: what if a GitHub repo came alive just like the toys? I started writing with something basic and enhanced it using Gemini Flash. Hope you'll like it.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;The Setup: The Developer's Stack&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The "Room" is the ultimate production stack. The classic, dependable tools that every developer loves and relies on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Woody (&lt;code&gt;python/cpython&lt;/code&gt;)&lt;/strong&gt;: The beloved, classic, highly readable leader of the repo ecosystem. He’s dependable, has been around forever, and is the favorite of the developer. He prides himself on clean architecture and readability.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Rex (&lt;code&gt;apache/jmeter&lt;/code&gt;)&lt;/strong&gt;: A massive, heavy-duty Java performance testing tool. He’s incredibly powerful but constantly anxious that modern, lightweight tools are going to make him look extinct.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Mr. Potato Head (&lt;code&gt;docker/cli&lt;/code&gt;)&lt;/strong&gt;: The ultimate container tool. You can literally swap his volumes, environment variables, and ports around to make him look like whatever you want.&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Slinky (&lt;code&gt;lodash/lodash&lt;/code&gt;)&lt;/strong&gt;: The utility tool that just exists to stretch and connect different data structures together smoothly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They all live in harmony on the machine, until a massive update drops...&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-11-693x1024.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-11-693x1024.png" alt="Toy Story: The Open-Source Ecosystem" width="693" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;The Inciting Incident: The Trendy New Framework&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The developer is starting a massive new enterprise cloud project. Suddenly, a sleek, shiny new arrival lands in the ecosystem with over 100k GitHub stars in its first week.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Buzz Lightyear (&lt;code&gt;facebook/react&lt;/code&gt;)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Buzz is high-tech, component-based, and completely delusional. He doesn’t realize he’s just an open-source library running on a local runtime. He genuinely believes he is a &lt;strong&gt;Space Ranger from Vercel deployed to the Edge Network&lt;/strong&gt;. He looks at the backend scripts and declares he will build a Virtual DOM to save the galaxy.&lt;/p&gt;

&lt;p&gt;Woody (&lt;code&gt;cpython&lt;/code&gt;) is furious. &lt;em&gt;"You aren't a full-stack engine! You're a frontend library! You're an npm package!"&lt;/em&gt; But the developer keeps starring &lt;code&gt;react&lt;/code&gt;, opening its issues, and ignoring &lt;code&gt;python&lt;/code&gt; scripts.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;The Interlude: Lost in Pizza Planet&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;In a heated argument over package management, Woody accidentally bumps Buzz out of the active IDE workspace. The other repos accuse Woody of a malicious &lt;code&gt;git rm&lt;/code&gt;. Determined to patch things over, Woody chases Buzz out of the environment.&lt;/p&gt;

&lt;p&gt;They end up stranded at &lt;strong&gt;Pizza Planet&lt;/strong&gt; a massive, chaotic public multi-tenant cluster. Hungry for a way back to a developer's machine, Buzz spots a glowing, neon structure: a massive monorepo cluster masquerading as a claw machine game.&lt;/p&gt;

&lt;p&gt;They climb inside, landing in a sea of hundreds of identical, tiny, lightweight &lt;strong&gt;Docker Microcontainers&lt;/strong&gt; (&lt;code&gt;alpine-linux/mini-images&lt;/code&gt;). They sit huddled together in their namespace pods, completely identical, staring upward in wonder.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Microcontainers:&lt;/strong&gt; &lt;em&gt;(In unison, staring at the cluster orchestrator)&lt;/em&gt; "Oooooooooh... &lt;strong&gt;The OpenClawwww.&lt;/strong&gt;"&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Buzz:&lt;/strong&gt; "Who is in charge here?"&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Microcontainer #1:&lt;/strong&gt; "The OpenClaw! It is an open-source automation engine. It hooks into our webhooks and schedules our lifecycles."&lt;/p&gt;



&lt;p&gt;Suddenly, a heavy, automated crane mechanism descends from the top of the repository cluster.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Microcontainer #2:&lt;/strong&gt; "The OpenClaw moves! It has selected a container!"&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Microcontainer #3:&lt;/strong&gt; "I have been chosen! I am being scheduled to a high-availability EC2 node! Farewell, my friends, I go to a better place... &lt;em&gt;Production!&lt;/em&gt;"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before Woody and Buzz can escape the cluster, &lt;strong&gt;Sid (&lt;code&gt;malicious-npm-bot&lt;/code&gt;)&lt;/strong&gt; a chaotic script-kiddie developer playing on the cluster drops a malicious token into the machine. The &lt;strong&gt;OpenClaw&lt;/strong&gt; descends, but instead of a container, its mechanical hook snags Woody and Buzz, dropping them right into Sid's dark dependency backpack.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;The Climax: The Dark Web of Dependency Hell&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Sid’s machine is a chaotic nightmare of dependency hell. He takes famous repos, strips their licenses, injects malware, and bundles them into mutated, broken franken-packages. He has strapped a volatile crypto-miner to Buzz, intending to deploy him to an unsecured AWS bucket.&lt;/p&gt;

&lt;p&gt;Woody realizes he can't save the day alone. He rallies Sid’s mutated, broken open-source forks. They break the prime directive of software: &lt;strong&gt;they execute without being called by a command line.&lt;/strong&gt; They glitch out Sid's IDE, spamming his screen with endless &lt;code&gt;Deprecated&lt;/code&gt; warnings and breaking changes until he panics, shuts down his PC, and goes outside.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;The Resolution: The Great Git Push&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Woody and Buzz race back to the developer's main machine, but the developer is in the middle of a massive migration. He is running a script to push his entire workspace to a new cloud organization.&lt;/p&gt;

&lt;p&gt;The migration truck is leaving! Woody and Buzz missed the initial commit. They scramble to find a way into the push. They spot a fast, high-velocity transport stream: &lt;strong&gt;&lt;code&gt;curl&lt;/code&gt; running over a high-speed fiber connection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They hitch a ride on a webhook, but the payload is too heavy. Buzz throws Woody ahead into the repository, sacrificing himself to an asynchronous timeout. Woody refuses to lose his friend. He grabs a &lt;code&gt;gzip&lt;/code&gt; compression rocket, ignites it, sweeps down, grabs Buzz, and they soar through the pipeline.&lt;/p&gt;

&lt;p&gt;They don't just land in the repo; they land right at the top of the &lt;strong&gt;&lt;code&gt;main&lt;/code&gt; branch&lt;/strong&gt;, fully compiled and perfectly integrated.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Post-Credits Scene:&lt;/strong&gt;&lt;/p&gt;



&lt;p&gt;&lt;code&gt;cpython&lt;/code&gt; and &lt;code&gt;react&lt;/code&gt; are now happily co-existing in a beautiful Django-React stack. Suddenly, the developer runs an installation command for a new repo that just dropped: &lt;strong&gt;&lt;code&gt;microsoft/autogen&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;&lt;em&gt;An army of autonomous AI Agents floods the repository.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Buzz:&lt;/strong&gt; "Woody, look! Multi-agent orchestration!"&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Woody:&lt;/strong&gt; &lt;em&gt;(Gulp)&lt;/em&gt; "Great..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;code&gt;THE STORY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY MERGE CONFLICTS, BROKEN DEPENDENCIES, OR EXISTENTIAL CRISES EXPERIENCED BY YOUR LOCAL SCRIPTS AFTER READING. 

Toy Story is © Disney/Pixar. All featured repositories belong to their rightful maintainers.&lt;/code&gt;&lt;/pre&gt;



</description>
      <category>ai</category>
      <category>writing</category>
    </item>
    <item>
      <title>JMeter vs k6 vs Locust in 2026: Which Load Testing Tool Should You Pick?</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Thu, 18 Jun 2026 20:33:01 +0000</pubDate>
      <link>https://dev.to/qainsights/jmeter-vs-k6-vs-locust-in-2026-which-load-testing-tool-should-you-pick-366f</link>
      <guid>https://dev.to/qainsights/jmeter-vs-k6-vs-locust-in-2026-which-load-testing-tool-should-you-pick-366f</guid>
      <description>&lt;p&gt;In this blog post, we will see a detailed, grounded comparison of the three most debated open-source load testing tools in 2026: Apache JMeter, Grafana k6, and Locust. All three are free. All three are production-proven. Yet they could not be more different in philosophy, architecture, and day-to-day experience.&lt;/p&gt;

&lt;p&gt;I have worked with all three across real-world projects, from legacy JDBC-heavy enterprise systems at work to lightweight microservice pipelines I test for my own side projects. The honest truth? There is no universal winner. But there is almost always a right answer for your specific situation, and that is what we will figure out today.&lt;/p&gt;

&lt;h2&gt;Why This Comparison Still Matters in 2026&lt;/h2&gt;

&lt;p&gt;Every year someone writes "JMeter is dead." Every year JMeter ships another release and shows up in another enterprise RFP.&lt;/p&gt;

&lt;p&gt;The market has not consolidated. Instead, it has stratified. k6 owns the developer-experience conversation. Locust owns the Python ecosystem. JMeter owns the protocol breadth and enterprise legacy. And in 2026, all three have meaningful updates worth knowing about before you pick a tool for your next project.&lt;/p&gt;

&lt;p&gt;Let me give you the ground truth, not marketing copy.&lt;/p&gt;





&lt;h2&gt;Quick Stats at a Glance&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Apache JMeter&lt;/th&gt;
&lt;th&gt;Grafana k6&lt;/th&gt;
&lt;th&gt;Locust&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Java (GUI + XML)&lt;/td&gt;
&lt;td&gt;Go runtime, JS/TS scripts&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latest Version&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5.6.3&lt;/td&gt;
&lt;td&gt;2.0.0 (May 2026)&lt;/td&gt;
&lt;td&gt;Latest on PyPI (May 2026)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Stars&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~9.4k&lt;/td&gt;
&lt;td&gt;~30.8k&lt;/td&gt;
&lt;td&gt;~27.9k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;License&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;AGPL-3.0&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concurrency Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Thread per VU&lt;/td&gt;
&lt;td&gt;Go goroutine per VU&lt;/td&gt;
&lt;td&gt;gevent greenlet per VU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Protocol Breadth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excellent (HTTP, JDBC, JMS, LDAP, MQTT, FTP...)&lt;/td&gt;
&lt;td&gt;Good (HTTP, gRPC, WebSocket)&lt;/td&gt;
&lt;td&gt;Good (HTTP, extensible via Python libs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI/CD Fit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GUI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (built-in)&lt;/td&gt;
&lt;td&gt;k6 Studio (separate app)&lt;/td&gt;
&lt;td&gt;Web UI (live stats only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloud Option&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BlazeMeter, OctoPerf&lt;/td&gt;
&lt;td&gt;Grafana Cloud k6&lt;/td&gt;
&lt;td&gt;Self-managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-protocol, legacy enterprise&lt;/td&gt;
&lt;td&gt;Modern APIs, developer teams&lt;/td&gt;
&lt;td&gt;Python shops, flexible scripting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;





&lt;h2&gt;Apache JMeter&lt;/h2&gt;

&lt;p&gt;JMeter was first released in 1998. That is not a typo. It turned 27 this year, and it is still actively maintained under the Apache Software Foundation.&lt;/p&gt;

&lt;p&gt;The latest stable release is 5.6.3. It requires Java 17 as the recommended runtime, and the team has already signaled that the next major version will drop Java 8 support entirely.&lt;/p&gt;

&lt;h3&gt;What JMeter Gets Right&lt;/h3&gt;

&lt;p&gt;JMeter's superpower is protocol coverage. Nothing else on this list comes close.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP / HTTPS&lt;/li&gt;



&lt;li&gt;JDBC (database connection testing)&lt;/li&gt;



&lt;li&gt;JMS&lt;/li&gt;



&lt;li&gt;LDAP&lt;/li&gt;



&lt;li&gt;MQTT&lt;/li&gt;



&lt;li&gt;FTP&lt;/li&gt;



&lt;li&gt;TCP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are testing a legacy enterprise system, a mainframe-adjacent API, or a backend that talks over JDBC, JMeter is often the only open-source option that handles it natively.&lt;/p&gt;

&lt;p&gt;The plugin ecosystem also deserves credit. The JMeter Plugins project (Head to &lt;a href="https://jmeter-plugins.org" rel="noopener noreferrer"&gt;https://jmeter-plugins.org&lt;/a&gt;) adds over 60 additional components. I have built and maintain several commercial plugins of my own, and the extensibility is genuinely solid once you understand the architecture.&lt;/p&gt;

&lt;h3&gt;Where JMeter Struggles in 2026&lt;/h3&gt;

&lt;p&gt;The XML-based &lt;code&gt;.jmx&lt;/code&gt; test plan format is the biggest pain point in a modern team. Git diffs on &lt;code&gt;.jmx&lt;/code&gt; files are nearly unreadable. Code review for JMeter scripts is painful. "Load testing as code" with JMeter is possible but requires discipline and tooling that does not come out of the box.&lt;/p&gt;

&lt;p&gt;The thread-per-user concurrency model also means JMeter is resource-hungry at scale. A single machine can generate fewer concurrent users than k6 or Locust on equivalent hardware. For large-scale tests, you need distributed mode or a cloud platform like BlazeMeter, which starts around $149/month for the basic plan.&lt;/p&gt;

&lt;p&gt;The GUI, while powerful, shows its age next to k6 Studio or even Locust's minimal web interface.&lt;/p&gt;

&lt;p&gt;You can check &lt;a href="https://jmeter.ai" rel="noopener noreferrer"&gt;Feather Wand&lt;/a&gt; if you want to infuse AI in your workflow. To measure the speed of LLM, you can check &lt;a href="https://iamspeed.dev" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Personal Observation&lt;/h3&gt;

&lt;p&gt;I was using JMeter daily at Salesforce for MuleSoft API performance testing. The GUI is genuinely useful for building complex request chains quickly. But the moment I need to commit a test plan to Git and do a proper review, it becomes painful.&lt;/p&gt;





&lt;h2&gt;Grafana k6&lt;/h2&gt;

&lt;p&gt;k6 is the most talked-about load testing tool in 2026, and the GitHub star count (30.8k at the time of writing) reflects that.&lt;/p&gt;

&lt;p&gt;Two major milestones happened back to back: k6 v1.0 dropped in May 2025 with TypeScript support, native extensibility without custom build pipelines, and SemVer stability guarantees. Then k6 v2.0.0 shipped on May 11, 2026, and it changed the game again.&lt;/p&gt;

&lt;h3&gt;What k6 2.0 Brought&lt;/h3&gt;

&lt;p&gt;The headline feature in k6 2.0 is AI-assisted testing workflows. This is not a gimmick. The release ships four new commands built specifically for agent-friendly development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;k6 x agent&lt;/code&gt;: bootstraps agentic testing workflows inside Claude Code, Codex, Cursor, and other AI coding assistants&lt;/li&gt;



&lt;li&gt;A built-in Model Context Protocol (MCP) server so AI agents can validate and run scripts, inspect results, and iterate without leaving the session&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;k6 x docs&lt;/code&gt;: gives agents and developers CLI access to k6 documentation and examples&lt;/li&gt;



&lt;li&gt;
&lt;code&gt;k6 x explore&lt;/code&gt;: lets agents browse the extension registry from the CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a new Assertions API, broader Playwright compatibility in the browser module, and a consolidated extension catalog that merges official and community extensions into one place.&lt;/p&gt;

&lt;h3&gt;What k6 Gets Right&lt;/h3&gt;

&lt;p&gt;The scripting experience is genuinely great for developers. You write JavaScript or TypeScript. Your IDE gives you autocomplete. Your CI pipeline runs it as a single binary with no JVM to provision.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 100,
  duration: '30s',
  thresholds: {
    http_req_duration: ['p(95)&amp;lt;500'],
    http_req_failed: ['rate&amp;lt;0.01'],
  },
};

export default function () {
  const res = http.get('https://api.example.com/health');
  check(res, {
    'status is 200': (r) =&amp;gt; r.status === 200,
  });
  sleep(1);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;k6 Studio (v1.13.1) is a desktop GUI with AI-powered auto-correlation. If you record a browser session, k6 Studio detects dynamic values like session tokens and CSRF tokens and generates correlation rules automatically. That is a feature JMeter has had for years via plugins, but k6 Studio does it through AI, without the XML.&lt;/p&gt;

&lt;h3&gt;Where k6 Struggles&lt;/h3&gt;

&lt;p&gt;Protocol coverage is more limited than JMeter. k6 is strong on HTTP, gRPC, and WebSocket. For JDBC, JMS, or LDAP, you are looking at community extensions or custom solutions.&lt;/p&gt;

&lt;p&gt;The AGPL-3.0 license is also worth flagging for commercial use cases. Check with your legal team if you are embedding k6 in a product.&lt;/p&gt;

&lt;h3&gt;Personal Observation&lt;/h3&gt;

&lt;p&gt;I built &lt;a href="https://iamspeed.dev" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt; (an LLM streaming benchmarker) and used k6 for the load side. The DX was excellent. TypeScript types in the IDE, a clean CLI, and Grafana integration out of the box. For any API-heavy workload where the protocol is HTTP or gRPC, k6 is my first recommendation in 2026.&lt;/p&gt;





&lt;h2&gt;Locust&lt;/h2&gt;

&lt;p&gt;Locust is the load testing tool for Python teams, and the May 2026 PyPI release confirms the project is alive and growing. It now officially supports Python 3.10 through 3.14.&lt;/p&gt;

&lt;h3&gt;What Locust Gets Right&lt;/h3&gt;

&lt;p&gt;Locust's model is simple: write Python classes that describe user behavior, run the tool, watch the web UI. No DSL to learn. No XML. No JVM.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;from locust import HttpUser, task, between

class APIUser(HttpUser):
    wait_time = between(1, 3)

    @task(3)
    def get_products(self):
        self.client.get("/api/products")

    @task(1)
    def get_health(self):
        self.client.get("/health")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Under the hood, Locust uses gevent greenlets instead of OS threads. This gives it excellent concurrency density. On the same 8 GB machine, Locust can handle roughly 5x more concurrent users than JMeter, according to TestDevLab's 2026 analysis.&lt;/p&gt;

&lt;p&gt;Because test files are plain Python, extending Locust to custom protocols is straightforward. Need to load test a proprietary queue or an LLM inference endpoint? Wrap the Python client library and drop it into a &lt;code&gt;HttpUser&lt;/code&gt; subclass. This is actually something I have done for AI workload benchmarking.&lt;/p&gt;

&lt;p&gt;Distributed testing is built in. You run a master process and any number of worker processes, scale horizontally, and the web UI aggregates everything.&lt;/p&gt;

&lt;h3&gt;Where Locust Struggles&lt;/h3&gt;

&lt;p&gt;The built-in reporting is minimal. The web UI gives you live stats during the run, but there is no built-in HTML report comparable to JMeter's dashboard or Gatling's output. Most teams pipe Locust metrics into Grafana via InfluxDB or Prometheus.&lt;/p&gt;

&lt;p&gt;There is no GUI for building test plans. Everything is code. That is great for developer teams but can be a barrier for non-technical stakeholders.&lt;/p&gt;

&lt;h3&gt;Personal Observation&lt;/h3&gt;

&lt;p&gt;Locust is my go-to tool when I am testing an LLM API or any endpoint where I need complex Python logic in the request flow, like computing HMAC signatures, calling a pre-step to generate tokens, or parsing streaming responses. The pure-Python model gives you the whole ecosystem to work with.&lt;/p&gt;





&lt;h2&gt;Head-to-Head Comparison&lt;/h2&gt;

&lt;h3&gt;Scripting Experience&lt;/h3&gt;

&lt;p&gt;JMeter gives you a GUI that is powerful but dated. Building a test plan with the GUI is fast for HTTP. Building one for gRPC or WebSocket requires plugins and some patience.&lt;/p&gt;

&lt;p&gt;k6 gives you a code editor and a TypeScript-aware test runner. The scripting is clean, the API is well-documented, and the extension ecosystem is growing fast.&lt;/p&gt;

&lt;p&gt;Locust gives you a Python file. Nothing else to install. If your team already writes Python, the onboarding time is near zero.&lt;/p&gt;

&lt;h3&gt;Concurrency Model&lt;/h3&gt;

&lt;p&gt;This is where architecture matters for real.&lt;/p&gt;

&lt;p&gt;JMeter runs one OS thread per virtual user. This is expensive. A mid-range machine typically maxes out around 300-500 concurrent threads before CPU and memory become the bottleneck, not the system under test.&lt;/p&gt;

&lt;p&gt;k6 runs each VU as a Go goroutine. Goroutines are lightweight. k6 can drive thousands of concurrent VUs from a single machine.&lt;/p&gt;

&lt;p&gt;Locust uses gevent greenlets, which are cooperative coroutines. Similar lightweight profile to goroutines. One machine can comfortably simulate thousands of users against an HTTP API.&lt;/p&gt;

&lt;h3&gt;CI/CD Integration&lt;/h3&gt;

&lt;p&gt;k6 wins this category cleanly. A single binary, no JVM, no Python dependency tree. The GitHub Actions integration is a config change. The threshold system lets you fail a pipeline based on p95 response time or error rate directly in the test script.&lt;/p&gt;

&lt;p&gt;Locust integrates well with CI/CD through headless mode (&lt;code&gt;locust --headless&lt;/code&gt;). You can define pass/fail criteria via exit codes and custom listeners.&lt;/p&gt;

&lt;p&gt;JMeter needs more setup: a JVM, a plugin directory, a &lt;code&gt;.jmx&lt;/code&gt; file committed to the repo, and some wrapper scripts to parse the output. It works, but it takes more effort to get right.&lt;/p&gt;

&lt;h3&gt;Reporting&lt;/h3&gt;

&lt;p&gt;JMeter ships a dynamic HTML report with response time graphs, latency percentiles, and error analysis. It is comprehensive out of the box.&lt;/p&gt;

&lt;p&gt;k6 pushes metrics to Grafana natively (local or cloud), and the k6 2.0 summary is significantly improved over previous versions. For cloud runs, the Grafana Cloud k6 dashboard is excellent.&lt;/p&gt;

&lt;p&gt;Locust's built-in report is minimal. Pipe to Grafana via Prometheus or InfluxDB for anything beyond a quick check.&lt;/p&gt;

&lt;h3&gt;Cloud Execution&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;JMeter&lt;/th&gt;
&lt;th&gt;k6&lt;/th&gt;
&lt;th&gt;Locust&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Managed Cloud&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BlazeMeter ($149/mo+), OctoPerf&lt;/td&gt;
&lt;td&gt;Grafana Cloud k6&lt;/td&gt;
&lt;td&gt;None (self-managed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual setup&lt;/td&gt;
&lt;td&gt;k6 Operator (official)&lt;/td&gt;
&lt;td&gt;Manual setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Distributed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Controller + agents via SSH&lt;/td&gt;
&lt;td&gt;k6 cloud run / k6 Operator&lt;/td&gt;
&lt;td&gt;Master + worker processes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;





&lt;h2&gt;The Metric Problem Nobody Talks About&lt;/h2&gt;

&lt;p&gt;This is something I always include when I write about load testing tools, because it catches teams off guard.&lt;/p&gt;

&lt;p&gt;Run the same test against the same endpoint using JMeter and k6, and you will see different response time numbers. Not because one tool is wrong. Because they measure different slices of the request lifecycle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JMeter starts the clock at the connection and stops when the last byte is received&lt;/li&gt;



&lt;li&gt;k6 breaks response time into granular phases: &lt;code&gt;http_req_connecting&lt;/code&gt;, &lt;code&gt;http_req_tls_handshaking&lt;/code&gt;, &lt;code&gt;http_req_waiting&lt;/code&gt;, &lt;code&gt;http_req_receiving&lt;/code&gt;
&lt;/li&gt;



&lt;li&gt;Locust, using gevent, can report higher response times under certain connection reuse configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OctoPerf's comparative study showed up to 15-20% variance in reported response times between tools running identical load against the same target. The practical takeaway: never compare baselines across tools. Establish baselines inside a single tool and track trends there.&lt;/p&gt;





&lt;h2&gt;Which Tool Should You Choose?&lt;/h2&gt;

&lt;p&gt;Use this decision tree:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose JMeter if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are testing JDBC, JMS, LDAP, FTP, or SOAP endpoints&lt;/li&gt;



&lt;li&gt;Your team uses GUI-driven test creation&lt;/li&gt;



&lt;li&gt;You have an existing JMeter investment and plugin ecosystem&lt;/li&gt;



&lt;li&gt;You work in enterprise environments where BlazeMeter or OctoPerf is already licensed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose k6 if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your stack is HTTP, gRPC, or WebSocket&lt;/li&gt;



&lt;li&gt;Your team writes JavaScript or TypeScript&lt;/li&gt;



&lt;li&gt;CI/CD integration is a first-class requirement&lt;/li&gt;



&lt;li&gt;You want AI-assisted test authoring in 2026 (k6 2.0's MCP server is real and it works)&lt;/li&gt;



&lt;li&gt;You want the best DX in the category right now&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose Locust if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your team is already Python-first&lt;/li&gt;



&lt;li&gt;You need deep customization of request logic (token generation, streaming parsing, custom protocols)&lt;/li&gt;



&lt;li&gt;You are testing LLM APIs or AI workloads where the request logic is non-trivial&lt;/li&gt;



&lt;li&gt;You want distributed testing without a managed cloud dependency&lt;/li&gt;
&lt;/ul&gt;





&lt;h2&gt;The Hybrid Stack Reality&lt;/h2&gt;

&lt;p&gt;Something the comparison articles rarely say: most mature teams run two tools.&lt;/p&gt;

&lt;p&gt;The practical 2026 default stack looks like one of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;k6 OSS for daily CI checks + Grafana Cloud k6 for quarterly capacity tests&lt;/li&gt;



&lt;li&gt;JMeter locally for protocol-rich scenarios + BlazeMeter for distributed runs&lt;/li&gt;



&lt;li&gt;Locust for API behavioral tests in Python + Prometheus/Grafana for dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have run exactly this kind of hybrid at QAInsights, using JMeter for the complex correlation scenarios and k6 for the lightweight API regression checks that live in CI. The tools complement each other more than they compete.&lt;/p&gt;





&lt;h2&gt;Final Verdict&lt;/h2&gt;

&lt;p&gt;There is no single best load testing tool in 2026. But there is a best tool for your context.&lt;/p&gt;

&lt;p&gt;If you are starting from scratch on a modern microservices stack, pick k6. The DX is excellent, k6 2.0's AI integration is ahead of everyone else, and the Grafana ecosystem is mature.&lt;/p&gt;

&lt;p&gt;If your Python team needs to write complex behavioral scripts, pick Locust. The gevent-based concurrency is efficient, the code is readable, and the Python ecosystem fills every gap.&lt;/p&gt;

&lt;p&gt;If you are in an enterprise environment testing JDBC, JMS, or anything beyond HTTP, pick JMeter. The protocol breadth is unmatched in open source, and the plugin ecosystem solves problems that other tools have not even attempted.&lt;/p&gt;

&lt;p&gt;What matters most is not which tool you pick. It is that you actually test under load before your users find the bottleneck for you.&lt;/p&gt;

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

&lt;p&gt;What tool are you using in your current project, and what made you choose it over the alternatives? Drop your answer in the comments below.&lt;/p&gt;

</description>
      <category>resources</category>
      <category>testing</category>
      <category>developers</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Fast.com for LLMs: Introducing iamspeed.dev</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Wed, 17 Jun 2026 16:50:20 +0000</pubDate>
      <link>https://dev.to/qainsights/i-built-a-fastcom-for-llms-introducing-iamspeeddev-54ek</link>
      <guid>https://dev.to/qainsights/i-built-a-fastcom-for-llms-introducing-iamspeeddev-54ek</guid>
      <description>&lt;p&gt;In this blog post, we will see how I built &lt;a href="https://iamspeed.dev/" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt;, a fast.com-style LLM API speed benchmark tool that measures Time to First Token (TTFT) and tokens-per-second throughput directly in your browser.&lt;/p&gt;

&lt;p&gt;If you have ever stared at a spinning cursor waiting for an LLM response and wondered "is this slow, or is it just me?" this tool is for you.&lt;/p&gt;

&lt;p&gt;The tool is designed for quick, lightweight benchmarking, modeled after the fast.com experience for internet speed tests. It uses an extensible provider adapter architecture, making it straightforward to add new providers such as Gemini or Groq. Planned additions include historical results, model comparison mode, and support for local models via Ollama.&lt;/p&gt;

&lt;p&gt;iamspeed.dev is an open-source, browser-based benchmarking tool for LLM APIs that measures two key performance metrics: Time to First Token (TTFT) and tokens-per-second throughput. It supports OpenAI and Anthropic providers and stores API keys locally using AES-GCM encryption, with no backend or data transmission.&lt;/p&gt;

&lt;h2&gt;The Problem That Sparked This&lt;/h2&gt;

&lt;p&gt;I spend a lot of time benchmarking systems. Load testing APIs, profiling microservices, measuring throughput it is what I do at QAInsights and at my day job.&lt;/p&gt;

&lt;p&gt;When LLMs started becoming part of production stacks, I noticed that most developers just eye-balled "it feels fast" or "it feels slow." There was no quick, browser-based tool you could open, configure your API key, and immediately get a concrete number.&lt;/p&gt;

&lt;p&gt;Tools like &lt;a href="https://artificialanalysis.ai/" rel="noopener noreferrer"&gt;artificial analysis&lt;/a&gt; do heavy-lifting comparisons across hundreds of models. But I wanted something lighter. Something you could open on a Tuesday afternoon and just run.&lt;/p&gt;

&lt;p&gt;That is exactly how &lt;a href="https://fast.com/" rel="noopener noreferrer"&gt;fast.com&lt;/a&gt; works for internet speed tests. You open it, it runs, you see a number. Done.&lt;/p&gt;

&lt;p&gt;So I built the same thing for LLM APIs: &lt;strong&gt;iamspeed.dev&lt;/strong&gt;.&lt;/p&gt;





&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fachu-2026-06-17-000829-558-1024x768.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fachu-2026-06-17-000829-558-1024x768.png" alt="Introducing iamspeed.dev" width="800" height="600"&gt;&lt;/a&gt;Introducing iamspeed.dev&lt;p&gt;&lt;/p&gt;

&lt;h1&gt;What Is iamspeed.dev?&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://iamspeed.dev/" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt; is an open-source, browser-based benchmarking tool for LLM APIs. It streams live tokens from supported providers OpenAI and Anthropic today and shows you real-time performance metrics as they happen.&lt;/p&gt;

&lt;p&gt;No backend. No data collection. No surprises.&lt;/p&gt;

&lt;p&gt;Your API key is stored locally in your browser using AES-GCM encryption, meaning it never leaves your machine.&lt;/p&gt;

&lt;p&gt;The interface is deliberately minimal, as shown below just a logo, a metric display, a Run button, and a settings panel. Inspired directly by the fast.com aesthetic.&lt;/p&gt;





&lt;h2&gt;Key Metrics: What Gets Measured&lt;/h2&gt;

&lt;p&gt;If you work with LLMs in production, you already know that raw response time is a misleading number. The two metrics that actually matter are:&lt;/p&gt;

&lt;h3&gt;1. Time to First Token (TTFT)&lt;/h3&gt;

&lt;p&gt;This is the time between sending your request and receiving the very first token back from the model. It reflects how quickly the LLM starts generating a response.&lt;/p&gt;

&lt;p&gt;TTFT is what users feel. A high TTFT means that awkward pause before anything appears on screen.&lt;/p&gt;

&lt;p&gt;For interactive applications, keeping TTFT low is critical. Reasoning models (extended thinking, deep think modes) can inflate TTFT by 5x to 30x because of the additional compute happening before the first visible token arrives.&lt;/p&gt;

&lt;h3&gt;2. Tokens Per Second (Throughput)&lt;/h3&gt;

&lt;p&gt;This is the rate at which the model streams tokens to you after the first one arrives. It is the "output speed" metric.&lt;/p&gt;

&lt;p&gt;High tokens per second means the text appears fast and fluid on screen. Low throughput feels choppy and slow even if the TTFT was acceptable.&lt;/p&gt;

&lt;p&gt;Together, these two numbers give you the full picture of how an LLM API performs for your use case.&lt;/p&gt;





&lt;h2&gt;Features at a Glance&lt;/h2&gt;

&lt;p&gt;Here is a quick summary of what iamspeed.dev supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live streaming output&lt;/strong&gt; with real-time metric updates&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;TTFT measurement&lt;/strong&gt; captured precisely at the moment the first token arrives&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Tokens/sec throughput&lt;/strong&gt; tracking updated continuously during generation&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;AES-GCM encrypted API key storage&lt;/strong&gt; local only, never transmitted&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;OpenAI provider support&lt;/strong&gt; (GPT-4o, GPT-4.1, and compatible models)&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Anthropic provider support&lt;/strong&gt; (Claude Sonnet, Claude Haiku, and more)&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Extensible provider architecture&lt;/strong&gt; via a clean &lt;code&gt;ProviderAdapter&lt;/code&gt; interface&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Responsive minimal UI&lt;/strong&gt; inspired by fast.com&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key thing I want to highlight is the local encryption. I have seen too many tools that ask for your API key and quietly send it somewhere. iamspeed.dev does not do that. Your key is AES-GCM encrypted and stored only in your browser's local storage.&lt;/p&gt;

&lt;p&gt;The provider architecture is clean and intentional. Each LLM provider is implemented as an adapter that satisfies the &lt;code&gt;ProviderAdapter&lt;/code&gt; interface. This makes adding new providers straightforward and keeps the core benchmark logic provider-agnostic.&lt;/p&gt;

&lt;p&gt;The project is hosted at &lt;a href="https://iamspeed.dev/" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt; and the full source is available on &lt;a href="https://github.com/QAInsights/iamspeed.dev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;





&lt;h2&gt;How to Run It Locally&lt;/h2&gt;

&lt;p&gt;Running iamspeed.dev locally takes under a minute. Here are the steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code&gt;git clone https://github.com/QAInsights/iamspeed.dev.git
cd iamspeed.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;ol start="2"&gt;
&lt;li&gt;Install dependencies:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;ol start="3"&gt;
&lt;li&gt;Start the development server:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;ol start="4"&gt;
&lt;li&gt;Head to &lt;code&gt;http://localhost:4321&lt;/code&gt; in your browser.&lt;/li&gt;



&lt;li&gt;Click the gear icon (Settings) and enter your OpenAI or Anthropic API key.&lt;/li&gt;



&lt;li&gt;Hit &lt;strong&gt;Run&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You will immediately see the tokens streaming in and the tokens/sec counter updating live, as shown below.&lt;/p&gt;

&lt;p&gt;Here are all the available commands:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm run dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start the dev server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build for production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm run preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preview the production build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run unit tests (Vitest)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm run test:e2e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run E2E tests (Playwright)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;





&lt;h2&gt;How to Add a New Provider&lt;/h2&gt;

&lt;p&gt;This is where the architecture really shines. If you want to add support for, say, Gemini or Groq, the process is clean:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new adapter file in &lt;code&gt;src/lib/providers/&lt;/code&gt;. Your adapter must implement the &lt;code&gt;ProviderAdapter&lt;/code&gt; interface.&lt;/li&gt;



&lt;li&gt;Register it in &lt;code&gt;src/lib/providers/index.ts&lt;/code&gt;.&lt;/li&gt;



&lt;li&gt;Add the provider metadata (name, models, etc.) to &lt;code&gt;src/lib/config.ts&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is it. No changes to the benchmark engine, no changes to the UI logic. The adapter pattern keeps concerns separated cleanly.&lt;/p&gt;

&lt;p&gt;I am planning to add more providers over time. If you want to contribute one, pull requests are welcome.&lt;/p&gt;





&lt;h2&gt;Why This Matters for Performance Engineers&lt;/h2&gt;

&lt;p&gt;I want to speak directly to performance engineers here for a second.&lt;/p&gt;

&lt;p&gt;We are used to measuring systems with JMeter, k6, Gatling. We understand throughput, latency percentiles, concurrency, think time. LLM APIs add a new dimension to all of this.&lt;/p&gt;

&lt;p&gt;When you are building an AI-powered product, you are not just measuring HTTP response time anymore. You are dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TTFT as a user-perceived latency metric&lt;/strong&gt; (equivalent to time-to-interactive in web perf)&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Streaming throughput&lt;/strong&gt; as a sustained delivery rate (not a one-shot measurement)&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Provider variability&lt;/strong&gt; the same model can behave very differently across regions and time of day&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Reasoning overhead&lt;/strong&gt; thinking models add invisible compute time before the first visible token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools like iamspeed.dev give you a quick sanity check. Before you design a full performance test suite for your LLM-powered API, run a quick benchmark here to understand your baseline numbers.&lt;/p&gt;

&lt;p&gt;I have written extensively about LLM performance metrics on the QAInsights blog and built the jmeter-llm-sampler plugin for measuring TTFT and TTLT in JMeter test plans. iamspeed.dev is the browser-friendly companion to those deeper tools.&lt;/p&gt;





&lt;h2&gt;What's Next&lt;/h2&gt;

&lt;p&gt;A few things I want to add to iamspeed.dev:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More providers&lt;/strong&gt;: Gemini, Groq, Mistral, and local Ollama support&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Historical results&lt;/strong&gt;: Run multiple benchmarks and compare them over time&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Model comparison mode&lt;/strong&gt;: Run the same prompt across two models side by side&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Shareable result links&lt;/strong&gt;: Generate a URL you can share with your team&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Prompt customization&lt;/strong&gt;: Let you choose the input prompt length to simulate different workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these sound useful to you, drop a star on the &lt;a href="https://github.com/QAInsights/iamspeed.dev" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; and let me know what you want to see first.&lt;/p&gt;





&lt;h2&gt;Try It Now&lt;/h2&gt;

&lt;p&gt;Head to &lt;a href="https://iamspeed.dev/" rel="noopener noreferrer"&gt;iamspeed.dev&lt;/a&gt;, configure your API key in settings, and hit Run.&lt;/p&gt;

&lt;p&gt;You will have your tokens-per-second number in about 10 seconds.&lt;/p&gt;

&lt;p&gt;The source code is MIT licensed and available at &lt;a href="https://github.com/QAInsights/iamspeed.dev" rel="noopener noreferrer"&gt;github.com/QAInsights/iamspeed.dev&lt;/a&gt;. Contributions are open.&lt;/p&gt;

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





&lt;p&gt;&lt;strong&gt;What LLM provider are you using in production today, and what TTFT are you seeing? Drop a comment below I would love to know how the numbers compare.&lt;/strong&gt;&lt;/p&gt;





</description>
      <category>ai</category>
      <category>webdev</category>
      <category>developers</category>
      <category>tooling</category>
    </item>
    <item>
      <title>How I Use Qwen Code Slash Commands to Build Achu App</title>
      <dc:creator>NaveenKumar Namachivayam ⚡</dc:creator>
      <pubDate>Wed, 17 Jun 2026 03:49:08 +0000</pubDate>
      <link>https://dev.to/qainsights/how-i-use-qwen-code-slash-commands-to-build-achu-app-5cm9</link>
      <guid>https://dev.to/qainsights/how-i-use-qwen-code-slash-commands-to-build-achu-app-5cm9</guid>
      <description>&lt;p&gt;In this blog post, we will see how I use Qwen Code's slash commands and workflow strategies to build &lt;a href="https://achu.app/" rel="noopener noreferrer"&gt;Achu&lt;/a&gt; my screenshot beautifier app without burning through tokens or losing context mid-session.&lt;/p&gt;

&lt;p&gt;If you haven't heard of &lt;a href="https://achu.app" rel="noopener noreferrer"&gt;Achu&lt;/a&gt;, it's a desktop app built with Electron + React + TypeScript. It does screenshot beautification, Privacy Guard (offline OCR redaction), Auto-Vibe (palette-extracted backgrounds), and an AI Bug Agent with GitHub integration. It's a side project I'm genuinely proud of, and Qwen Code has become my go-to agentic coding CLI for it.&lt;/p&gt;

&lt;p&gt;A developer shares their day-to-day workflow for using Qwen Code, an open-source agentic coding CLI, to build Achu, a desktop screenshot beautification app built with Electron, React, and TypeScript. The post covers how slash commands like /init, /plan, /compress, /remember, and /btw are used to manage context, reduce token costs, and maintain consistent output across sessions.&lt;/p&gt;

&lt;p&gt;The core approach centers on spec-driven planning through iterative /plan sessions before any code is written, combined with parallel subagents for independent tasks and strict context hygiene using /compress and /clear. Additional practices include pointing the model at library source code instead of documentation and using /remember to persist architectural decisions across sessions.&lt;/p&gt;

&lt;p&gt;This isn't a tutorial about what Qwen Code is. It's about how I actually use it day-to-day, the slash command tricks I rely on, and the discipline it takes to get real work done with an LLM in a terminal.&lt;/p&gt;

&lt;p&gt;It all started with Google Antigravity, but the 5 hours reset and weekly limits is killing my productivity and thinking flow. I had to switch to more affordable and open source model where I chose Qwen.&lt;/p&gt;





&lt;h2&gt;Why Qwen Code?&lt;/h2&gt;

&lt;p&gt;I've tried Claude Code, Gemini CLI, and a bunch of others. Qwen Code is open source, has excellent subagent support, a rich slash command system, and Qwen Max is genuinely strong at reasoning through complex TypeScript and Electron internals.&lt;/p&gt;

&lt;p&gt;My go-to model is &lt;strong&gt;Qwen Max&lt;/strong&gt;. For lighter tasks like &lt;code&gt;/recap&lt;/code&gt; or prompt suggestions I set a fast model with &lt;code&gt;/model --fast qwen3-coder-flash&lt;/code&gt; to keep costs down.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-7-1024x320.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-7-1024x320.png" alt="" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h2&gt;The /init and Project Context Setup&lt;/h2&gt;

&lt;p&gt;The very first thing I do when I start on a new project or return to Achu after a few days is run:&lt;/p&gt;

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

&lt;p&gt;This analyzes the current directory and generates an initial context file essentially giving Qwen Code a map of the project. It picks up folder structure, key files, and creates a baseline understanding before I say a single word.&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;/init&lt;/code&gt;, I manually add a few paragraphs about the project. I treat this like writing a team onboarding doc for a new developer. I tell Qwen what Achu is, what the current milestone is, what tech stack we're on, and what the known constraints are (like Electron IPC boundaries, the Upstash Redis integration, or the Gumroad-based monetization model).&lt;/p&gt;

&lt;p&gt;This upfront investment saves enormous amounts of back-and-forth later.&lt;/p&gt;





&lt;h2&gt;Spec-Driven Planning with /plan&lt;/h2&gt;

&lt;p&gt;When I want to build a new feature, I don't just dump a vague request and hope for the best. I use &lt;code&gt;/plan&lt;/code&gt; to switch Qwen Code into planning mode.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/plan Implement the Privacy Guard redaction pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In plan mode, Qwen analyzes and thinks, but does not touch any files. This is key. It's the agentic equivalent of "think before you act."&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-8-1024x322.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-8-1024x322.png" alt="Plan mode" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I actually do is run multiple turns in plan mode to iterate the spec. I think of a "spec" as the formal artifact that describes what should be built the interface contracts, the data flow, the error paths, the acceptance criteria. It's not a vague idea. It's something precise enough that a developer (or subagent) could implement it.&lt;/p&gt;

&lt;p&gt;The loop looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt; enter planning mode&lt;/li&gt;



&lt;li&gt;Describe the feature in detail what it does, what it doesn't do, edge cases&lt;/li&gt;



&lt;li&gt;Ask Qwen to propose an approach&lt;/li&gt;



&lt;li&gt;Push back on anything that doesn't fit the architecture&lt;/li&gt;



&lt;li&gt;Ask for the revised plan&lt;/li&gt;



&lt;li&gt;Repeat 2-3 times until the spec is solid&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The quality of implementation is almost entirely determined by the quality of the spec. This multi-turn refinement before a single line of code is written is the most valuable habit I've developed using any agentic coding tool.&lt;/p&gt;

&lt;p&gt;By default, Qwen will ask followup questions. But it is always recommended to tell the model to ask questions.&lt;/p&gt;





&lt;h2&gt;Subagents for Async Work&lt;/h2&gt;

&lt;p&gt;Once the spec is locked in, I use subagents aggressively for any work that can happen independently.&lt;/p&gt;

&lt;p&gt;Qwen Code's subagent system lets you define specialized agents as Markdown files in &lt;code&gt;.qwen/agents/&lt;/code&gt;. Each agent has its own system prompt, tool allowlist, and model. You can call them explicitly or let Qwen delegate automatically.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-9-1024x423.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-9-1024x423.png" alt="" width="799" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Achu, I have a few custom subagents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;testing subagent&lt;/strong&gt; focused on Vitest and Electron testing patterns (more on this below)&lt;/li&gt;



&lt;li&gt;A &lt;strong&gt;code reviewer subagent&lt;/strong&gt; that runs in &lt;code&gt;plan&lt;/code&gt; mode and only reads files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key power here is &lt;strong&gt;Fork Subagents&lt;/strong&gt; when Qwen needs to run multiple things in parallel, it can implicitly fork. Forks inherit the parent context, run in the background, and share the prompt cache prefix. This means if I ask Qwen to "investigate the IPC handler for Privacy Guard, the Ollama integration, and the Upstash Redis voting flow simultaneously," it can fork three parallel agents without tripling my token costs.&lt;/p&gt;

&lt;p&gt;I explicitly phrase tasks as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run these three investigations in parallel using subagents and report back."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This keeps the main conversation focused and lets the grunt work happen concurrently.&lt;/p&gt;

&lt;p&gt;A project-level subagent config lives at &lt;code&gt;.qwen/agents/testing.md&lt;/code&gt; and looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---
name: testing
description: "Writes Vitest unit tests and Electron integration tests for Achu. Use PROACTIVELY for any test-related tasks."
approvalMode: auto-edit
tools:
  - read_file
  - write_file
  - read_many_files
  - run_shell_command
---

You are a testing specialist for an Electron + React + TypeScript app.
Follow Vitest conventions. Mock Electron IPC using vitest-mock-extended.
Always write both positive and negative test cases.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The phrase "Use PROACTIVELY" in the description is important it signals to the main model to delegate testing tasks here without being asked explicitly.&lt;/p&gt;





&lt;h2&gt;Context Hygiene: /summary, /compress, and /clear&lt;/h2&gt;

&lt;p&gt;This is where most people fail with long agentic sessions. They let the context grow unbounded until the model starts hallucinating, forgetting earlier instructions, or producing inconsistent output. I've learned to treat context like memory on a constrained machine.&lt;/p&gt;

&lt;p&gt;My hygiene rules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After a major chunk of work is done:&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;This generates a project summary from the conversation history. I save this externally and reference it when restarting sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When the context window is getting full:&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;This replaces chat history with a compressed summary, freeing up tokens while preserving the semantic essence of what was discussed. Think of it as a lossy but practical checkpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When Qwen starts steering away:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the model starts going off-track giving answers that don't match the project constraints, suggesting patterns we've already ruled out, or just losing the thread. I don't argue. If it happens twice in a row, I clear:&lt;/p&gt;

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

&lt;p&gt;Then I reload context from scratch using &lt;code&gt;/init&lt;/code&gt; and a fresh description. Two drifts is my hard limit. The discipline here is resisting the urge to keep "fixing" a bad session. It's cheaper to restart clean.&lt;/p&gt;





&lt;h2&gt;Watching Context and Usage with /context and /stats&lt;/h2&gt;

&lt;p&gt;I watch these two commands constantly.&lt;/p&gt;

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

&lt;p&gt;Shows a breakdown of what's consuming the context window right now system prompt, conversation history, tool results. If I see tool results bloating the context, I know a &lt;code&gt;/compress&lt;/code&gt; is coming.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/context detail
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Shows per-item breakdown. Useful when one massive file read is eating 40% of the window.&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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-10.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%2Fqainsights.com%2Fwp-content%2Fuploads%2F2026%2F06%2Fimage-10.png" alt="" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Gives detailed session statistics tokens used, API calls, cost estimates. I check this before and after big operations. It's how I keep tabs on spend, especially on Qwen Max which isn't the cheapest model.&lt;/p&gt;

&lt;p&gt;Keeping an eye on these is the agentic equivalent of watching memory usage in a production system. Ignore it and you'll pay for it.&lt;/p&gt;





&lt;h2&gt;Pointing to Source Directories Instead of Docs&lt;/h2&gt;

&lt;p&gt;This one is a significant productivity trick that I don't see talked about enough.&lt;/p&gt;

&lt;p&gt;When Qwen needs to understand a third-party library, the default approach is to tell it to fetch the docs URL. The problem is that docs are often incomplete, outdated, or optimized for humans rather than LLMs.&lt;/p&gt;

&lt;p&gt;What I do instead: I download the library source and point the conversation directly at it using &lt;code&gt;@&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@./vendor/upstash-redis/src Tell me how the pipeline API works
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or with a deeper path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@./node_modules/@electron/remote/src/main Explain the context bridge setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Qwen reads the actual implementation. No guessing from docs. No hallucination about API signatures that changed in the last major version.&lt;/p&gt;

&lt;p&gt;I keep a &lt;code&gt;vendor/&lt;/code&gt; folder in the project root where I clone or copy source for critical dependencies. This makes &lt;code&gt;@&lt;/code&gt; references stable and reproducible.&lt;/p&gt;

&lt;p&gt;For Achu specifically, I've pointed Qwen at the Ollama TypeScript client source, the llava-phi3 model integration code, and parts of the Electron forge config. The answers I get are ground-truth accurate instead of approximately correct.&lt;/p&gt;





&lt;h2&gt;Persistent Memory with /remember and /dream&lt;/h2&gt;

&lt;p&gt;Some things should survive session boundaries. My preferences, key architectural decisions, constraints Qwen needs to always respect. I use &lt;code&gt;/remember&lt;/code&gt; for these.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/remember Always use Electron's contextBridge for IPC. Never use remote module.
/remember Achu uses oklch color space. Do not suggest hex values without conversion.
/remember Free tier users get 3 exports per day. Pro users are unlimited.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These get persisted in Qwen's memory store and are injected into future sessions automatically.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/dream&lt;/code&gt; is the manual trigger for auto-memory consolidation. Qwen's auto-memory runs in the background, but if I want to force a consolidation pass after a long session to make sure the important discoveries from the current session get persisted I run:&lt;/p&gt;

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

&lt;p&gt;Think of it as flushing the cache to disk before shutting down.&lt;/p&gt;

&lt;p&gt;To review and manage what's been remembered, I use:&lt;/p&gt;

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

&lt;p&gt;This opens the Memory Manager dialog where I can edit or delete entries. I audit this occasionally. Stale memories can be just as harmful as no memories.&lt;/p&gt;





&lt;h2&gt;The /btw Trick for Side Questions&lt;/h2&gt;

&lt;p&gt;This is my favourite quality-of-life command.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/btw What's the difference between contextBridge.invoke and contextBridge.exposeInMainWorld?
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;/btw&lt;/code&gt; sends a parallel API call with recent conversation context (up to the last 20 messages) and shows the response above the composer without touching the main conversation at all. The main session continues uninterrupted.&lt;/p&gt;

&lt;p&gt;I use this constantly for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quick clarifications while in the middle of implementation&lt;/li&gt;



&lt;li&gt;Checking a TypeScript type signature without derailing a planning session&lt;/li&gt;



&lt;li&gt;Double-checking a shell command before running it via &lt;code&gt;!&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The response doesn't become part of conversation history. It's a throwaway lookup. This is genuinely useful and I'm surprised more CLI tools don't have something like it.&lt;/p&gt;





&lt;h2&gt;Uncommon Commands Worth Knowing&lt;/h2&gt;

&lt;p&gt;Beyond the commands I use daily, here are a few from the docs that are genuinely underrated:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/restore&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Restores files to their state before a tool execution. If a Qwen action made a mess, you can list recent tool executions with &lt;code&gt;/restore&lt;/code&gt; and roll back a specific one with &lt;code&gt;/restore &amp;lt;ID&amp;gt;&lt;/code&gt;. Think of it as a targeted undo for AI changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/loop&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Runs a prompt on a recurring schedule:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/loop 5m check the build output and report any new warnings
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I use this occasionally when I'm doing a long build and want Qwen to monitor for me while I do something else. It's a lightweight cron for conversational tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/recap&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generates a one-line summary of where the session left off. If I step away for more than five minutes, Qwen auto-triggers this when I return:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;? Implementing the Privacy Guard redaction pipeline. Next step: wire the OCR output into the bounding-box overlay renderer.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Incredibly useful for picking up after an interruption without scrolling through history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/approval-mode auto-edit&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I trust the current task scope, I switch to auto-edit to let Qwen make file changes without prompting me every time. I reserve &lt;code&gt;yolo&lt;/code&gt; mode for throwaway branches only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/directory&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adds multiple directories to the workspace context:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/dir add ./src,./tests,./electron
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Useful when the feature spans multiple root-level directories that Qwen wouldn't automatically scope to.&lt;/p&gt;





&lt;h2&gt;My Qwen Code Workflow Summary&lt;/h2&gt;

&lt;p&gt;Here's the workflow I follow for every non-trivial feature in Achu:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start clean&lt;/strong&gt; &lt;code&gt;/init&lt;/code&gt; + add project context manually&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Spec first&lt;/strong&gt;  use &lt;code&gt;/plan&lt;/code&gt; in multiple turns until the spec is solid&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Delegate async tasks&lt;/strong&gt;  use subagents for parallel investigations and implementation&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Monitor context&lt;/strong&gt;  &lt;code&gt;/context detail&lt;/code&gt; regularly, &lt;code&gt;/compress&lt;/code&gt; proactively&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Log source truth&lt;/strong&gt;  point &lt;code&gt;@&lt;/code&gt; at source directories, not docs&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Remember decisions&lt;/strong&gt;  &lt;code&gt;/remember&lt;/code&gt; for anything that should persist&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Quick questions&lt;/strong&gt;  &lt;code&gt;/btw&lt;/code&gt; without breaking flow&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;Clear if it drifts&lt;/strong&gt; two steering-away moments is my hard limit for &lt;code&gt;/clear&lt;/code&gt;
&lt;/li&gt;



&lt;li&gt;
&lt;strong&gt;End of session&lt;/strong&gt; &lt;code&gt;/dream&lt;/code&gt; to consolidate memory, &lt;code&gt;/summary&lt;/code&gt; to save the state&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This isn't magic. It's discipline. The LLM doesn't make you disciplined you have to bring that yourself. But when you apply this workflow consistently, the output quality is noticeably better than freeform chatting with an AI.&lt;/p&gt;

&lt;p&gt;If you're building something with Qwen Code, try the spec-first approach. The twenty minutes you spend in &lt;code&gt;/plan&lt;/code&gt; mode iterating the spec will save you three hours of correcting implementation drift.&lt;/p&gt;





&lt;p&gt;Happy Agentic Coding, Testing, Shipping, Learning, whatever :) !&lt;/p&gt;

&lt;p&gt;What's your biggest challenge with agentic coding workflows staying in context, or getting the model to follow architectural constraints? Let me know in the comments.&lt;/p&gt;





</description>
      <category>ai</category>
      <category>productivity</category>
      <category>development</category>
      <category>resources</category>
    </item>
  </channel>
</rss>
