<?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: Stephan Miller</title>
    <description>The latest articles on DEV Community by Stephan Miller (@eristoddle).</description>
    <link>https://dev.to/eristoddle</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%2F18795%2F5f6c41b8-6033-4887-937a-2ebdfe623d2e.jpeg</url>
      <title>DEV Community: Stephan Miller</title>
      <link>https://dev.to/eristoddle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eristoddle"/>
    <language>en</language>
    <item>
      <title>Firecrawl CLI Setup: Skip the Installer That Rewrites Your Editors</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Wed, 09 Sep 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/firecrawl-cli-setup-skip-the-installer-that-rewrites-your-editors-2klj</link>
      <guid>https://dev.to/eristoddle/firecrawl-cli-setup-skip-the-installer-that-rewrites-your-editors-2klj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F24byux7y2whh5k1ea19b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F24byux7y2whh5k1ea19b.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/eristoddle/what-to-do-when-your-ai-coding-agent-cant-read-a-web-page-2f0i"&gt;last post&lt;/a&gt; I gave the Firecrawl setup three sentences and moved on, because the post was about the fetch skill I was building and not about installation.&lt;/p&gt;

&lt;p&gt;The install itself is one command. Everything around the install is what you have to watch: an installer that wants to configure every editor on your machine, an auth screen that reports two contradictory things in consecutive lines, and a shell issue that cost me an API key I could only copy once. Plus one fork in the road worth deciding before you start, which is whether the tool should run as a command or as a resident MCP server.&lt;/p&gt;

&lt;p&gt;So here is the setup told properly, for somebody who is installing &lt;a href="https://firecrawl.link/stephan-miller" rel="noopener noreferrer"&gt;Firecrawl&lt;/a&gt; right now and would rather not spend the time I spent. Everything below was run on this machine against CLI version 1.23.3.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install With npm, Not With the Installer&lt;/li&gt;
&lt;li&gt;CLI or MCP: Pick the One That Stays Out of the Way&lt;/li&gt;
&lt;li&gt;The Auth Screen That Contradicts Itself&lt;/li&gt;
&lt;li&gt;
The Almost-Right Command

&lt;ul&gt;
&lt;li&gt;If you are on fish&lt;/li&gt;
&lt;li&gt;The afternoon the almost-right command cost me&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Prove It Works Before You Trust It&lt;/li&gt;
&lt;li&gt;The Setup Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install With npm, Not With the Installer
&lt;/h2&gt;

&lt;p&gt;The command you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; firecrawl-cli

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

&lt;/div&gt;



&lt;p&gt;That is the whole install. You get a &lt;code&gt;firecrawl&lt;/code&gt; binary on your &lt;code&gt;PATH&lt;/code&gt;, symlinked into your global node modules like any other npm package, and nothing else on your machine changes.&lt;/p&gt;

&lt;p&gt;The docs will also offer you a curl-piped-to-shell one-liner, and the CLI ships a &lt;code&gt;firecrawl init&lt;/code&gt; command. Both do considerably more than install a binary. Here is &lt;code&gt;init&lt;/code&gt; describing itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usage: firecrawl init [options] [template]

Set up Firecrawl: install CLI, authenticate, add integrations, and scaffold a
template

Arguments:
  ...

Options:
  --all Explicitly install skills to all detected agents (default
                       unless --agent is used)
  -y, --yes Run init non-interactively; skills still install globally
                       across all detected agents unless --agent is used
  -g, --global Install skills globally (user-level, default)
  -a, --agent &amp;lt;agent&amp;gt; Install skills to a specific agent
  -k, --api-key &amp;lt;key&amp;gt; Authenticate with this API key (skips interactive login)
  --skip-install Skip global CLI installation
  --skip-auth Skip authentication
  --skip-skills Skip skills installation

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

&lt;/div&gt;



&lt;p&gt;Read the &lt;code&gt;-y&lt;/code&gt; line again. Skills still install globally across all detected agents. The non-interactive flag does not mean “do less.” It means “do all of it without asking.”&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;init&lt;/code&gt; is not alone. There are four separate commands in this CLI whose actual job is writing Firecrawl into tools that are not Firecrawl:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkpmy1dycpu8u8nv118pq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkpmy1dycpu8u8nv118pq.jpg" alt="Install With npm, Not With the Installer" width="800" height="447"&gt;&lt;/a&gt;&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;What it does to your machine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installs the CLI, authenticates, and pushes agent skills to every detected agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installs &lt;code&gt;skills&lt;/code&gt;, &lt;code&gt;workflows&lt;/code&gt;, &lt;code&gt;mcp&lt;/code&gt;, or &lt;code&gt;defaults&lt;/code&gt; individually&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;make default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Makes Firecrawl the default provider for supported workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;launch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installs the Firecrawl MCP server into an agent, then starts that agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The one that gave me pause is &lt;code&gt;setup&lt;/code&gt;, and specifically its undo flag, which is documented as “Undo setup defaults by re-enabling native web tools where supported.” Read that again. The undo re-enables your native web tools, which means the thing being undone disabled them. A scraping vendor’s installer, in its default path, turns off the web fetching your coding agent already had.&lt;/p&gt;

&lt;p&gt;I guess that is the reasonable end state of a competitive market where the install experience is a growth channel, and Firecrawl is far from the only tool doing it. It is also the thing I do not want, because I would like to be the one who decides what is in their context.&lt;/p&gt;

&lt;p&gt;Skip all four. One npm install does the job.&lt;/p&gt;

&lt;p&gt;You can confirm you got the right outcome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;which firecrawl
&lt;span class="c"&gt;# /opt/homebrew/bin/firecrawl&lt;/span&gt;

firecrawl &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# 1.23.3&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  CLI or MCP: Pick the One That Stays Out of the Way
&lt;/h2&gt;

&lt;p&gt;I run Firecrawl through the CLI rather than its MCP server. This is the same verdict I landed on with Playwright.&lt;/p&gt;

&lt;p&gt;An MCP server is resident. Its tool definitions sit in the agent’s context on every single request, whether or not this particular request has anything to do with scraping. That is a fixed tax paid in tokens and in attention, on every turn, for a capability I use maybe twice a week.&lt;/p&gt;

&lt;p&gt;A CLI is not resident. The agent runs a command, the output goes to a file, and between calls the tool occupies exactly nothing. When I need Firecrawl, a skill tells the agent the command to run. When I do not, there is no evidence in the context that Firecrawl exists.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;launch&lt;/code&gt; command exists specifically to install the MCP server into your agent and then start it, and it knows about &lt;code&gt;claude&lt;/code&gt;, &lt;code&gt;code/vscode&lt;/code&gt;, &lt;code&gt;codex&lt;/code&gt;, &lt;code&gt;codex-app&lt;/code&gt;, &lt;code&gt;hermes&lt;/code&gt;, &lt;code&gt;openclaw&lt;/code&gt;, and &lt;code&gt;opencode&lt;/code&gt;. That is a well-built feature and I understand why people want it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdifc2a0fuurterh5kd6k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdifc2a0fuurterh5kd6k.jpg" alt="CLI or MCP: Pick the One That Stays Out of the Way" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the counterargument, because there is one. An MCP server means the agent discovers the capability on its own. It sees a scraping tool in its tool list and reaches for it without being told. With the CLI approach, something has to tell the agent that Firecrawl is an option, which in my case is a skill I had to write. If you do not want to write that glue, the MCP server is genuinely the faster road.&lt;/p&gt;

&lt;p&gt;I already had the glue. So for me the CLI wins on the only part I care about, which is that a background tool beats one that takes over the screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Auth Screen That Contradicts Itself
&lt;/h2&gt;

&lt;p&gt;Get your API key from the dashboard, then check your configuration. This is what &lt;code&gt;firecrawl view-config&lt;/code&gt; printed for me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│ Firecrawl Configuration │
└─────────────────────────────────────────┘

Status: ✓ Authenticated

API Key: Not set
API URL: https://api.firecrawl.dev
Config: /Users/&amp;lt;you&amp;gt;/Library/Application Support/firecrawl-cli

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

&lt;/div&gt;



&lt;p&gt;Authenticated, with a check mark. API key not set. Two lines apart, both delivered with total confidence.&lt;/p&gt;

&lt;p&gt;I spent real time on this, and the answer turns out to be that neither line is lying. They are answering two different questions but forgot to label which is which.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Status:&lt;/code&gt; reflects live authentication state, including the &lt;code&gt;FIRECRAWL_API_KEY&lt;/code&gt; environment variable. &lt;code&gt;API Key:&lt;/code&gt; reflects only a key stored in the CLI’s own config file, which is empty when you authenticate through the environment instead of through &lt;code&gt;firecrawl config&lt;/code&gt;. Two auth paths, two readouts, stacked adjacently with no indication that they are reading different sources.&lt;/p&gt;

&lt;p&gt;You can prove it in one command. Clear the environment variable and run the same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; FIRECRAWL_API_KEY firecrawl view-config


Status: Not authenticated

Run any &lt;span class="nb"&gt;command &lt;/span&gt;to start authentication, or use:
  firecrawl config Authenticate with browser or API key

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

&lt;/div&gt;



&lt;p&gt;The status flipped, which means the status was reading the environment variable all along.&lt;/p&gt;

&lt;p&gt;The command you actually want is &lt;code&gt;firecrawl --status&lt;/code&gt;, which does not have this problem because it names its source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  🔥 firecrawl cli v1.23.3

  ● Authenticated via FIRECRAWL_API_KEY
  Concurrency: 0/2 jobs (parallel scrape limit)
  Credits: 1,324 / 1,000 (132% left this cycle)
  .firecrawl: not found - no local cache
  .gitignore: missing - add .firecrawl/ to ignore cache

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

&lt;/div&gt;



&lt;p&gt;“Authenticated via FIRECRAWL_API_KEY.” That is the whole fix. One flag, and the ambiguity disappears. Use &lt;code&gt;--status&lt;/code&gt; and forget &lt;code&gt;view-config&lt;/code&gt; exists.&lt;/p&gt;

&lt;p&gt;(Yes, it says I have 132% of my credits left after running some crawls this month. I am choosing to accept this gift and not ask questions.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Almost-Right Command
&lt;/h2&gt;

&lt;p&gt;Now the part that actually cost me something.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F84fr3qsqb9v8nfzaxcrb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F84fr3qsqb9v8nfzaxcrb.jpg" alt="The Almost-Right Command That Cost Me an API Key" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key goes in an environment variable called &lt;code&gt;FIRECRAWL_API_KEY&lt;/code&gt;. On bash or zsh, that means one line in your shell’s startup file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ~/.bashrc on bash, ~/.zshrc on zsh&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;FIRECRAWL_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fc-your-key-here

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

&lt;/div&gt;



&lt;p&gt;Then open a new terminal, or run &lt;code&gt;source ~/.bashrc&lt;/code&gt; in the one you already have. The export does not reach backwards into shells that were already running.&lt;/p&gt;

&lt;p&gt;Here is the trap, and it is not specific to any one shell. Typing &lt;code&gt;export FIRECRAWL_API_KEY=fc-...&lt;/code&gt; straight at your prompt instead of putting it in the startup file works perfectly for the rest of that session and then evaporates when you close the window. Everything you test in the next five minutes succeeds. That is the worst possible failure mode, because success is exactly what convinces you to stop paying attention and move on.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you are on fish
&lt;/h3&gt;

&lt;p&gt;This is where it bit me, and fish makes the hole a little easier to fall into, because it has four variable scopes instead of one and the two that matter here differ by a single letter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wrong. Dies when you close the terminal.&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; FIRECRAWL_API_KEY fc-your-key-here

&lt;span class="c"&gt;# Right. Persists across sessions.&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-Ux&lt;/span&gt; FIRECRAWL_API_KEY fc-your-key-here

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-x&lt;/code&gt; exports it to child processes. &lt;code&gt;-U&lt;/code&gt; makes it universal, which in fish means it survives the terminal closing. You need both.&lt;/p&gt;

&lt;h3&gt;
  
  
  The afternoon the almost-right command cost me
&lt;/h3&gt;

&lt;p&gt;I asked an AI assistant for the fish command to set an environment variable permanently, and got back &lt;code&gt;set -x&lt;/code&gt;. I closed the terminal, came back, was not authenticated, asked again, phrased it more emphatically, and got back &lt;code&gt;set -x&lt;/code&gt; again. Somewhere in there I closed the tab with the API key on it.&lt;/p&gt;

&lt;p&gt;I had not saved the key anywhere else, because I had just watched it get set successfully and had no reason to think I would need it again. So I rotated it and started over, which took the whole thing from a five-minute setup to something dumber. Copy the key into a password manager before you touch your shell config, and none of this can happen to you.&lt;/p&gt;

&lt;p&gt;The generalizable lesson has nothing to do with fish. AI-assisted setup fails in a specific and nasty shape: it hands you the almost-right command. A wrong command errors out immediately and you fix it in ten seconds. An almost-right command succeeds, validates cleanly, and fails an hour later, after you have thrown away the thing you would need to recover. &lt;code&gt;set -x&lt;/code&gt; is not a wrong answer to “set an environment variable in fish.” It is a wrong answer to “set it permanently,” and the word doing the work is the one the model dropped. Bash has the identical hole with a bare &lt;code&gt;export&lt;/code&gt; at the prompt.&lt;/p&gt;

&lt;p&gt;Whatever shell you are on, open a fresh terminal and confirm the thing you just set is still there before you trust it. That is the entire takeaway and it applies well beyond this tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prove It Works Before You Trust It
&lt;/h2&gt;

&lt;p&gt;Do not skip this. The whole point of the previous section is that a broken setup can look fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft3pzivywx6yzugtpmmos.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft3pzivywx6yzugtpmmos.jpg" alt="Prove It Works Before You Trust It" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firecrawl scrape https://example.com &lt;span class="nt"&gt;--only-main-content&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; smoke.md &lt;span class="nt"&gt;--timing&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-o&lt;/code&gt; flag is not optional in spirit. Without it the scraped page goes to stdout, and if you happen to smoke test something larger than &lt;code&gt;example.com&lt;/code&gt; you will dump an entire article into your terminal. The &lt;code&gt;--timing&lt;/code&gt; flag gives you a status line worth seeing.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Timing:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"requestTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-08T23:59:53.881Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"390ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Scrape&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="mi"&gt;08376&lt;/span&gt;&lt;span class="err"&gt;-c&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="mi"&gt;-73&lt;/span&gt;&lt;span class="err"&gt;bf-bc&lt;/span&gt;&lt;span class="mi"&gt;28-411202792&lt;/span&gt;&lt;span class="err"&gt;b&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;smoke.md&lt;/code&gt; contains actual markdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Example Domain&lt;/span&gt;

This domain is for use in documentation examples without needing permission. Avoid use in operations.

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Learn more&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://iana.org/domains/example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;A broken key looks like this, and thankfully it is loud rather than silent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Unauthorized: Invalid token

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

&lt;/div&gt;



&lt;p&gt;One more thing while you are here. Scrapes with multiple URLs get cached into a &lt;code&gt;.firecrawl/&lt;/code&gt; directory in your working directory, and the &lt;code&gt;--status&lt;/code&gt; output nags you about this every time, whether or not you are anywhere near a git repo. When you are in one, listen to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".firecrawl/"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore

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

&lt;/div&gt;



&lt;p&gt;Committing a cache directory full of scraped pages is a bad afternoon waiting to happen, and it is the kind of thing you only notice three weeks later in a diff.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup Summary
&lt;/h2&gt;

&lt;p&gt;Stripped of everything above, the working setup is four lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; firecrawl-cli
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export FIRECRAWL_API_KEY=fc-your-key-here'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
firecrawl &lt;span class="nt"&gt;--status&lt;/span&gt;
firecrawl scrape https://example.com &lt;span class="nt"&gt;--only-main-content&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; smoke.md

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

&lt;/div&gt;



&lt;p&gt;On zsh, swap &lt;code&gt;~/.bashrc&lt;/code&gt; for &lt;code&gt;~/.zshrc&lt;/code&gt;. On fish, line two is &lt;code&gt;set -Ux FIRECRAWL_API_KEY fc-your-key-here&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Install, key, verify, prove. Nothing writes into your editors, nothing sits in your agent’s context, and you know it works because you watched it work.&lt;/p&gt;

&lt;p&gt;The mess I spent an afternoon in was not really Firecrawl’s mess. It was two things that are now true of most developer tools: the installer has become a growth channel, so its default path is maximal rather than minimal, and the auth surface has grown enough paths that the status readout can no longer say one clear thing. Both of those will be true of the next tool you install too. The defense is the same either way, which is to install the binary, wire it up yourself, and run one command that proves it before you build anything on top of it.&lt;/p&gt;

&lt;p&gt;Next in this series I start actually using the thing, which means the first real recipe. This post exists so that one does not have to open with a paragraph about environment variables.&lt;/p&gt;

</description>
      <category>firecrawl</category>
    </item>
    <item>
      <title>GPT-6 Astra and Fable 5.1 Landed the Same Week. Read the Footnote.</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 08 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/gpt-6-astra-and-fable-51-landed-the-same-week-read-the-footnote-29j5</link>
      <guid>https://dev.to/eristoddle/gpt-6-astra-and-fable-51-landed-the-same-week-read-the-footnote-29j5</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvkuyviowqasvzmyfwho9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvkuyviowqasvzmyfwho9.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For about a month now I’ve been writing the same obituary. American AI lab ships nothing. Google ships a fourth Flash instead of the model it actually promised. Cheap Chinese open-weight models quietly eat the frontier from the bottom while everyone waits for a flagship that keeps slipping. I had the funeral playlist queued up.&lt;/p&gt;

&lt;p&gt;Then over three days the corpse sat up and shipped two flagships. Anthropic dropped Claude Fable 5.1 on September 1. OpenAI dropped GPT-6 Astra on September 3. They landed tied for the top of the intelligence charts, both priced at a flat ten dollars in and fifty out, and just like that the premium ceiling the cheap models spent all summer erasing was back.&lt;/p&gt;

&lt;p&gt;And here’s the part I didn’t see coming. In the exact same week, down at the other end of the market where nobody films the keynote, the cheapest-good-model crown finally changed hands. Both ends of the board moved at once. Let me walk you through it, and then give you the table you actually came here for.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The West remembered it makes models&lt;/li&gt;
&lt;li&gt;Meanwhile, down in the bargain bin, a crown changed hands&lt;/li&gt;
&lt;li&gt;The cheapskate picks&lt;/li&gt;
&lt;li&gt;Google shipped another Flash while the real thing pretrains&lt;/li&gt;
&lt;li&gt;What is coming&lt;/li&gt;
&lt;li&gt;The honest version&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The West remembered it makes models
&lt;/h2&gt;

&lt;p&gt;Start with Fable 5.1, because Anthropic set the tone.&lt;/p&gt;

&lt;p&gt;This is the follow-up to Fable 5, and Anthropic did the thing where they beat their own more expensive model with it. Fable 5.1 finishes ahead of Opus 5 on every category they published. Terminal-Bench-Science jumped to 52.6 percent against Opus 5’s 29.0. Their knowledge-work benchmark, GDPval-AA v2, went to 1853 against Opus 5’s 1824. Same sticker as before, ten and fifty per million, but cache reads got cut 75 percent to a quarter per million tokens, which matters more than it sounds if you run anything with a big fixed context.&lt;/p&gt;

&lt;p&gt;On the Artificial Analysis Intelligence Index it lands at number one. And here’s where you have to read the label. Every Fable 5.1 score on that leaderboard is tagged “with fallback.” That means the headline number quietly blends in a weaker model’s answers whenever a safety classifier refuses the real one, at a frequency nobody discloses. Anthropic pulled the same move on the Opus 5 chart back in July. The number is real. The footnote is load-bearing. The number-one model on the board isn’t purely the number-one model.&lt;/p&gt;

&lt;p&gt;Two days later OpenAI answered with GPT-6. Yes, six. GPT-6 Astra, ten and fifty per million, a 1.05 million token context, staged rollout to a handful of orgs first and then the ChatGPT tiers and the API “over the coming days.” It ties Fable 5.1 at the top of the intelligence index. On computer use it does 72.6 percent on OSWorld 2.0 at roughly 47 percent less time per task than GPT-5.6 Sol, which is the stat that actually matters for agent workloads.&lt;/p&gt;

&lt;p&gt;Then it gets weird. Astra “saturates” FrontierMath Tier 4 at 97.6 percent, ARC-AGI-3 at 99.9 percent, and ExploitBench at a clean 100 percent. That last one is an offensive-security benchmark. A frontier model that fully solves the “can you write a working exploit” test. And the 99.9 on ARC is measured “under OpenAI’s provider adapter harness,” which is the kind of phrase you learn to slow down and read twice, because a benchmark run inside the vendor’s own harness is graded homework. To round it out, OpenAI is shipping a program called Daybreak that loosens safeguards for vetted organizations. So the model that aced the exploit test also gets an official channel to relax its guardrails. If that gives you the same feeling the GLM-5.3 “too good at hacking to ship on time” story gave you last month, you’re paying attention.&lt;/p&gt;

&lt;p&gt;The thing to take away isn’t “which one wins.” They’re basically tied and it’ll take Arena weeks to sort them out, because Arena always lags a launch by a couple weeks while votes pile up. The thing to take away is that both American labs shipped their best model in one window at the same premium price, and the summer story about the West being asleep is, for now, dead. With an asterisk on each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meanwhile, down in the bargain bin, a crown changed hands
&lt;/h2&gt;

&lt;p&gt;Here’s the part I’ve been tracking for six weeks and finally get to close out.&lt;/p&gt;

&lt;p&gt;For six straight roundups the answer to “what is the cheapest model that is actually good” never moved. It was MiMo v2.5 Pro from Xiaomi. Eighty-seven cents per million output, open weights, and it kept turning up as the cheapest model inside the competitive band of four different Arena categories, week after week. It was the anchor. I could set my watch by it.&lt;/p&gt;

&lt;p&gt;Then last week GLM-5.3-Flash from Z.ai showed up cheaper and, on the hard benchmarks, smarter. The only reason I didn’t crown it on the spot was votes. Arena marks a rating “preliminary” until enough people have voted on it, and GLM-5.3-Flash was sitting on a couple thousand shaky votes while MiMo had fifty thousand solid ones. So I called it the emerging pick, kept MiMo as the printed anchor, and wrote down the tripwire: if GLM-5.3-Flash holds cheapest-in-band once the votes firm up, the spine has genuinely shifted.&lt;/p&gt;

&lt;p&gt;This week the votes firmed up. GLM-5.3-Flash is now the cheapest model in the competitive band for Overall, Coding, Instruction Following, and Hard Prompts, on real vote counts, and where it overlaps MiMo it out-rates it. In Overall it sits at 1474 with 4,672 votes for fifty cents per million output. MiMo is at 1468 for eighty-seven cents. Cheaper and higher. The six-week reign is over. MiMo’s the runner-up now, and it’s still a perfectly good runner-up with ten to twenty times the vote count, which is exactly why I keep it in the table.&lt;/p&gt;

&lt;p&gt;The catch, because there’s always a catch. GLM-5.3-Flash scores mid on the hard-reasoning index, a 42 where the frontier models are in the fifties. It’s preference-strong and cheap, not a deep-reasoning machine. It’s also slow, about 60 output tokens a second against a median north of 70, which compounds in agent loops where every step waits on the last. And the cheapest price you’ll see quoted for it, seven and a half cents in and a quarter out, is a launch promo that expires September 9. List is fifteen and fifty cents. Build your budget on the list price, not the promo, unless you enjoy surprises on the tenth.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheapskate picks
&lt;/h2&gt;

&lt;p&gt;Same method as always. For each Arena category I take the leader’s rating, draw a band 50 points below it, and find the cheapest model that still sits inside that band. The whole premise is that Arena ratings cluster tight at the top, so the category leader is usually only a rounding error better than something 20 to 100 times cheaper. I compute the band from the full table in code, not by eyeballing the first screen, because eyeballing it is how you delete the entire cheap tail and crown the cheapest expensive model by accident. Ask me how I know.&lt;/p&gt;

&lt;p&gt;Bands this week ran 56 deep in Overall, about 63 in Coding, and thin in Math where the whole board is still preliminary. Arena data dated around September 2.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ leader out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ pick out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;claude-fable-5 (1507)&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1474, #29)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−33&lt;/td&gt;
&lt;td&gt;~100×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;claude-opus-4-7-high (1552)&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1534, #9)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−18&lt;/td&gt;
&lt;td&gt;50×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-fable-5 (1504)&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;Gemini 3-Flash (1459, #27)&lt;/td&gt;
&lt;td&gt;$3&lt;/td&gt;
&lt;td&gt;−45&lt;/td&gt;
&lt;td&gt;~16.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-high (1514)&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1465, #34)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−49&lt;/td&gt;
&lt;td&gt;50×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-high (1533)&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1496, #31)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−37&lt;/td&gt;
&lt;td&gt;50×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;claude-fable-5 (1529, prelim)&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;Gemini 3.7-Flash-high (1524, #4)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−5&lt;/td&gt;
&lt;td&gt;~13×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few notes on reading that. The Coding line is the loudest one on the board: GLM-5.3-Flash is ranked ninth in coding, top-ten, for fifty cents per million. The catch there is 1,274 votes, still on the thin side, so if you want certainty over savings, MiMo at rank 26 with 15,813 votes for eighty-seven cents is the steadier bet. In Hard Prompts, GLM-5.3-Flash and MiMo are literally tied at 1496; GLM is cheaper, MiMo has twelve times the votes. Take your pick based on whether you trust the number or the sample size.&lt;/p&gt;

&lt;p&gt;Creative Writing stays a Gemini story because GLM-5.3-Flash never cracked that band, and Math is a low-confidence mess this week, thin preliminary votes top to bottom and no pick under $3.75, so treat that row as a suggestion and not a promise.&lt;/p&gt;

&lt;p&gt;The one thing I won’t do is pretend both value picks are fast. They’re not. GLM-5.3-Flash and MiMo are both slow. If you’re wiring one into an autonomous agent that chains dozens of calls, the fifty-cent price tag can balloon into a fifty-cent-per-call wall-clock tax. Cheap and slow is a real trade, not a free lunch. Know which one your workload cares about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Google shipped another Flash while the real thing pretrains
&lt;/h2&gt;

&lt;p&gt;Quick check-in on Google, who continue to run the strangest release cadence in the business.&lt;/p&gt;

&lt;p&gt;On September 2 they shipped Gemini 3.8 Flash. That’s the third Flash release in six weeks. It costs exactly what 3.7 Flash cost, 75 cents in and $3.75 out, and beats it on every benchmark they published, plus there’s a locked-down 3.8 Flash Cyber sibling for security work. It’s a genuinely good, cheap coding-and-agent workhorse, and it already shows up at number eight overall on Arena.&lt;/p&gt;

&lt;p&gt;But it’s built on the 3.7 base, not a new one, and it’s shipping instead of the Gemini 3.5 Pro they promised back in the spring, which has been quietly shelved after missing so many dates I lost count. The real model, Gemini 4, just “cleared pretraining” with strong preliminary results and the largest training run in Google’s history. No benchmarks, no price, no date, late 2026 if you believe the tea leaves. So Google’s strategy remains: ship a steady drip of excellent Flash models to stay in the headlines while the actual next-generation model bakes in the background. It’s working, in the sense that they’re still in the conversation. It’s also the fourth time this summer I’ve written that exact paragraph.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is coming
&lt;/h2&gt;

&lt;p&gt;Two things worth watching.&lt;/p&gt;

&lt;p&gt;Grok 4.7 is the loud one. Musk said on September 2 it would be out “in ten days,” which points at roughly September 12. It’s a 2.1 trillion parameter model, up 40 percent from Grok 4.6, and part of its training data comes from SpaceX internal engineering records, which is either the most interesting or the most concerning detail depending on your mood. There’s no model card, no price, no benchmark table, and no API id yet, so treat the date as a tweet and not a commitment.&lt;/p&gt;

&lt;p&gt;Gemini 4, covered above, is the other. Pretraining done, everything else unknown.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest version
&lt;/h2&gt;

&lt;p&gt;The clean narrative would be that the West is back and the story is over. It’s not that clean.&lt;/p&gt;

&lt;p&gt;Yes, Fable 5.1 and GPT-6 Astra are real, and yes they’re good, and yes the premium ceiling exists again. But both of them shipped with a footnote you have to read before you trust the headline. One blends a weaker model into its own benchmark and doesn’t tell you how often. The other aced an exploit-writing test and comes with a program to loosen its own safety rails. That’s not a reason to dismiss them. It’s a reason to read the harness section before you quote the number.&lt;/p&gt;

&lt;p&gt;And the more durable story is the one nobody put on a stage. The cheapest genuinely good model on the board is a fifteen-cent open-weight model from Z.ai that just took a crown a Xiaomi model held for a month and a half. The frontier got a loud, expensive reload this week. The floor got quietly cheaper. If you’re actually shipping something and paying the bill yourself, guess which one changes your life more.&lt;/p&gt;

&lt;p&gt;I’ll be back next week to see whether Grok 4.7 shows up on the twelfth or whether “ten days” means what it usually means.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
    </item>
    <item>
      <title>Obsidian Dropbox Sync: A Setup Guide</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 03 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/obsidian-dropbox-sync-a-setup-guide-2ajl</link>
      <guid>https://dev.to/eristoddle/obsidian-dropbox-sync-a-setup-guide-2ajl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4hxeki598pc1sc7gqcxg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4hxeki598pc1sc7gqcxg.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have synced my Obsidian vaults through Dropbox since I started using Obsidian.&lt;/p&gt;

&lt;p&gt;Today I ran one command across my whole Dropbox folder to see how much damage that did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ~/Dropbox &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*conflicted copy*"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;6,735.&lt;/p&gt;

&lt;p&gt;Of those, 6,517 are inside my Obsidian vaults, dating back to October 2023. And not one of them is a note. Every Dropbox-plus-Obsidian guide warns you that Dropbox is going to shred your notes, and in all that time it has never shredded one of mine. It shreds something else, constantly.&lt;/p&gt;

&lt;p&gt;If you are still deciding which method to use, start with &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-across-all-your-devices-including-free-methods-1mi5"&gt;my guide to syncing Obsidian for free on every device&lt;/a&gt;, which is the “which one” page. This one assumes you already picked Dropbox and want to run it without losing anything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desktop to Desktop Is Already Solved&lt;/li&gt;
&lt;li&gt;Mobile Is Where Dropbox Stops Being Dropbox&lt;/li&gt;
&lt;li&gt;The Remotely Save Trap That Quietly Duplicates Your Vault&lt;/li&gt;
&lt;li&gt;What Actually Conflicts, and It Is Not Your Notes&lt;/li&gt;
&lt;li&gt;Teach Dropbox to Ignore the Machinery&lt;/li&gt;
&lt;li&gt;Does an Obsidian Vault Blow Past the 2GB Free Tier?&lt;/li&gt;
&lt;li&gt;Dropbox Versus Obsidian Sync, With Real Numbers&lt;/li&gt;
&lt;li&gt;Cleaning Up the Conflicted Copies You Already Have&lt;/li&gt;
&lt;li&gt;Frequently Asked Questions&lt;/li&gt;
&lt;li&gt;What I Would Tell Someone Starting Today&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Desktop to Desktop Is Already Solved
&lt;/h2&gt;

&lt;p&gt;Put the vault in your Dropbox folder. Install Dropbox on the other computer. Open the vault. Done.&lt;/p&gt;

&lt;p&gt;That is the whole setup. Dropbox has done real two-way folder sync on desktop for a very long time and it is genuinely good at it.&lt;/p&gt;

&lt;p&gt;There are exactly two settings that turn this from “solved” into “where did my vault go,”:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selective sync&lt;/strong&gt; removes a folder from your hard drive while keeping it in your account. &lt;a href="https://help.dropbox.com/sync/selective-sync-overview" rel="noopener noreferrer"&gt;Dropbox’s own docs&lt;/a&gt; call it a way “to save space on your computer without deleting the files themselves,” which is true and also means Obsidian opens to an empty vault.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Online-only files&lt;/strong&gt; are worse, because they look like they work. The file stays visible as a placeholder and downloads when something opens it. Fine for a folder of PDFs. Not fine for Obsidian, which walks every file in the vault to build its link graph and search index on every launch. You are asking a note app to stream 2,700 files off the network before it can show you a backlink.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep the vault local and available offline. If you need disk space, make some other folder online-only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile Is Where Dropbox Stops Being Dropbox
&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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9at9bddnc1iwgk8f5gj7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9at9bddnc1iwgk8f5gj7.jpg" alt="Mobile Is Where Dropbox Stops Being Dropbox" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Dropbox mobile app is not a sync client. It is a file browser with an offline toggle, and Obsidian mobile needs a real folder full of real files sitting on the device.&lt;/p&gt;

&lt;p&gt;Offline files live inside the Dropbox app rather than in a folder your other apps can open. And making an entire &lt;em&gt;folder&lt;/em&gt; available offline “is only available to customers on Dropbox Plus, Family, Professional, Standard, Advanced, and Enterprise plans,” so on a free account you can’t do this.&lt;/p&gt;

&lt;p&gt;So on desktop, Dropbox is the whole answer. On mobile, Dropbox is storage and something else does the syncing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On iPhone and iPad&lt;/strong&gt; , that something else is &lt;a href="https://github.com/remotely-save/remotely-save" rel="noopener noreferrer"&gt;Remotely Save&lt;/a&gt;, a plugin that runs inside Obsidian and talks to the Dropbox API directly. iOS never lets an outside app near the vault, so the sync has to happen from inside. That is covered in more depth in &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-on-iphone-and-ipad-for-free-in-2026-427p"&gt;my guide to syncing Obsidian on iPhone and iPad for free&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Android&lt;/strong&gt; , you get a choice, and it was made for you back when you created the vault. Android asks whether to put the vault in device storage or app storage, and app storage means no outside app can ever see the vault, which rules out every folder-sync tool. If your vault is in device storage, &lt;a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync" rel="noopener noreferrer"&gt;Dropsync&lt;/a&gt; from &lt;a href="https://metactrl.com/" rel="noopener noreferrer"&gt;MetaCtrl&lt;/a&gt; does real two-way folder sync against Dropbox and is still actively developed. If it is in app storage, you are back to Remotely Save. I went through that whole decision in &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-on-android-for-free-41m"&gt;how to sync Obsidian on Android for free&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Remotely Save Trap That Quietly Duplicates Your Vault
&lt;/h2&gt;

&lt;p&gt;Dropbox is in Remotely Save’s free tier. You do not need PRO for it. Install the plugin the &lt;a href="https://dev.to/eristoddle/how-to-install-activate-and-update-obsidian-plugins-4d2p"&gt;usual way&lt;/a&gt;, open its settings, pick Dropbox, hit Auth, follow the link, approve, and come back. Two minutes.&lt;/p&gt;

&lt;p&gt;Then read the permission text on that approval screen. The plugin gets to “read and write files in your Dropbox’s &lt;code&gt;/Apps/remotely-save&lt;/code&gt; folder.” Not your Dropbox. That folder.&lt;/p&gt;

&lt;p&gt;Say your desktop vault lives at &lt;code&gt;~/Dropbox/Notes/Writing&lt;/code&gt;, which is a completely sensible place to put it. You install Remotely Save on your phone, authorize Dropbox, and it starts syncing to &lt;code&gt;/Apps/remotely-save/Writing&lt;/code&gt; instead. You now have two vaults in one Dropbox account. Your laptop writes to one, your phone writes to the other and neither knows the other exists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhrlr261y4p3vsy4qhdyg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhrlr261y4p3vsy4qhdyg.jpg" alt="The Remotely Save Trap That Quietly Duplicates Your Vault" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fix is stupid: move your desktop vault into the app folder. Here is my actual machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; ~/Dropbox/Apps/remotely-save/&lt;span class="k"&gt;*&lt;/span&gt;/
&lt;span class="go"&gt;/Users/eristoddle/Dropbox/Apps/remotely-save/Eristoddle-Org/
/Users/eristoddle/Dropbox/Apps/remotely-save/Test/
/Users/eristoddle/Dropbox/Apps/remotely-save/The Novelist/
/Users/eristoddle/Dropbox/Apps/remotely-save/Writing/

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

&lt;/div&gt;



&lt;p&gt;Four vaults, all living where the plugin already has permission. Desktop Dropbox syncs that folder like any other folder. Mobile Remotely Save syncs into the same place.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Conflicts, and It Is Not Your Notes
&lt;/h2&gt;

&lt;p&gt;Back to those 6,517 conflicted copies. Here is where they live in my main vault:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;Conflicted copies&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.smart-env/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5,669&lt;/td&gt;
&lt;td&gt;AI embedding cache from a plugin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.obsidian/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;811&lt;/td&gt;
&lt;td&gt;Plugin data, workspace state, settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.git/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;Git index and FETCH_HEAD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actual notes&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Zero. In almost three years.&lt;/p&gt;

&lt;p&gt;Once you see it, the reason is obvious. A markdown note is a few kilobytes, you edit it on one device at a time, and you type slower than Dropbox syncs. The window where two machines write the same note is about as wide as the odds of you opening that note on your phone and your laptop within the same ninety seconds.&lt;/p&gt;

&lt;p&gt;Plugin state is the opposite of all of that. &lt;code&gt;workspace.json&lt;/code&gt; gets rewritten every time you move a pane. A plugin’s &lt;code&gt;data.json&lt;/code&gt; gets rewritten on every settings change and sometimes on a timer. An embeddings cache gets rewritten by whichever instance is indexing, which is all of them, all the time. Two Obsidian windows on two machines hammer those files whether or not you are touching a note. Of my &lt;code&gt;.obsidian&lt;/code&gt; conflicts, 675 are some plugin’s &lt;code&gt;data.json&lt;/code&gt; and 93 are &lt;code&gt;workspace.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And I will own the dumbest row in that table. Those 35 conflicts in &lt;code&gt;.git/&lt;/code&gt; exist because I run the Obsidian Git plugin on a vault that also lives in Dropbox, which is precisely the “never run two sync systems on one vault” rule I wrote in the pillar post. Which is the ideal, but since I haven’t lost anything, who cares.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teach Dropbox to Ignore the Machinery
&lt;/h2&gt;

&lt;p&gt;Dropbox has a real ignore feature that hardly gets used, probably because it is an extended file attribute instead of a dotfile. On macOS with the classic Dropbox folder at &lt;code&gt;~/Dropbox&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xattr &lt;span class="nt"&gt;-w&lt;/span&gt; com.dropbox.ignored 1 ~/Dropbox/Apps/remotely-save/Writing/.smart-env

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foyxtolc2ln51ay53w6ti.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foyxtolc2ln51ay53w6ti.jpg" alt="Teach Dropbox to Ignore the Machinery" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If macOS has moved your Dropbox to &lt;code&gt;~/Library/CloudStorage/Dropbox&lt;/code&gt;, it is the File Provider variant instead (and this took me a while to realize):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xattr &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'com.apple.fileprovider.ignore#P'&lt;/span&gt; 1 ~/Library/CloudStorage/Dropbox/path/to/.smart-env

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

&lt;/div&gt;



&lt;p&gt;Windows, in PowerShell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Set-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\Users\you\Dropbox\Writing\.smart-env'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;com.dropbox.ignored&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;attr &lt;span class="nt"&gt;-s&lt;/span&gt; com.dropbox.ignored &lt;span class="nt"&gt;-V&lt;/span&gt; 1 ~/Dropbox/Writing/.smart-env

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now read the warning that comes with it.&lt;/strong&gt; From &lt;a href="https://help.dropbox.com/sync/ignored-files" rel="noopener noreferrer"&gt;Dropbox’s docs&lt;/a&gt;: the ignored file “will be deleted from the Dropbox server and your other devices.”&lt;/p&gt;

&lt;p&gt;That is a delete, not an exclude. So do not point it at &lt;code&gt;.obsidian&lt;/code&gt; wholesale unless you genuinely want separate plugin setups per device, which some people do. Point it at the caches that regenerate themselves and are worthless to move between machines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.smart-env/&lt;/code&gt; or whatever your AI plugin calls its embeddings cache&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.trash/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.git/&lt;/code&gt; if you are syncing that vault with git too&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.obsidian/workspace.json&lt;/code&gt;, if you are tired of your phone’s pane layout landing on your desktop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The other catch: the attribute is local to the machine you set it on. Set it on one laptop and your other laptop will happily regenerate the file and upload it again. You have to set it everywhere. Annoying, but it is a five-minute job that ends a problem which has been running since 2023. Will I fix it on my devices? Has anything broken yet? Same answer and laziness wins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does an Obsidian Vault Blow Past the 2GB Free Tier?
&lt;/h2&gt;

&lt;p&gt;Dropbox Basic is &lt;a href="https://www.dropbox.com/plans" rel="noopener noreferrer"&gt;2 GB&lt;/a&gt;. Every guide tells you a text vault will never come close. Let me check that against a real one.&lt;/p&gt;

&lt;p&gt;My &lt;code&gt;Writing&lt;/code&gt; vault, 2,727 markdown notes accumulated over years of daily use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;find Writing &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.md"&lt;/span&gt; &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"*/.obsidian/*"&lt;/span&gt; &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; + | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;span class="go"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;67.5 MB.&lt;/p&gt;

&lt;p&gt;So yes, the guides are right. My notes are 3% of the free tier and I could write at this pace until I die without filling it.&lt;/p&gt;

&lt;p&gt;The vault on disk is 7.6 GB.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.git/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2.5 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.smart-env/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1.8 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.obsidian/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1.8 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Attachments/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1.2 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Everything else, including all my notes&lt;/td&gt;
&lt;td&gt;273 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The notes are a rounding error. The vault is almost four times over the free tier, and every bit of the overage is git history, plugin binaries, an embeddings cache, and images I pasted in without thinking. So the ignore attribute in the last section is not a tidiness exercise. On a free Dropbox account it is the difference between this working and not working at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwtvl6cxqwq9kigcznki4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwtvl6cxqwq9kigcznki4.jpg" alt="Dropbox Versus Obsidian Sync, With Real Numbers" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dropbox Versus Obsidian Sync, With Real Numbers
&lt;/h2&gt;

&lt;p&gt;The comparison people actually want is whether to keep doing this or just pay Obsidian.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://obsidian.md/sync" rel="noopener noreferrer"&gt;Obsidian Sync Standard&lt;/a&gt; is $5 a month, or $4 a month billed annually. You get 1 GB of storage, a 5 MB maximum file size, and 1 month of version history. Sync Plus is $10 a month, or $8 annually, for 10 GB, 200 MB files, and 12 months of history.&lt;/p&gt;

&lt;p&gt;Dropbox lists Plus at $9.99 a month for 2 TB, and Basic at 2 GB free.&lt;/p&gt;

&lt;p&gt;So the math splits three ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You already pay for Dropbox.&lt;/strong&gt; Dropbox plus Remotely Save costs zero additional dollars, and Sync Standard is $48 a year to solve problems you mostly do not have. This is me. This is why I have never subscribed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You pay for nothing yet.&lt;/strong&gt; Free Dropbox is 2 GB and Sync Standard is 1 GB, so on raw storage the free tier wins, but only if you keep the machinery out of the vault. Closer than it looks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You have big attachments.&lt;/strong&gt; Sync Standard’s 5 MB per-file cap is brutal, and one phone photo can exceed it. Dropbox’s limits are nowhere near anything a vault will hit. If your vault holds PDFs or images, Sync Standard is out and you are comparing against Sync Plus at $96 a year.&lt;/p&gt;

&lt;p&gt;What the $48 buys is conflict handling and version history. Obsidian Sync resolves conflicts at the note level and keeps a month of history. Dropbox knows what a byte range is and forks the file. For me that has been worth nothing, because the things Dropbox forks are caches. If you routinely write on two devices at once, it is worth more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaning Up the Conflicted Copies You Already Have
&lt;/h2&gt;

&lt;p&gt;Look before you delete. This lists them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ~/Dropbox/Apps/remotely-save &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*conflicted copy*"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Confirm every hit is inside a &lt;code&gt;.obsidian&lt;/code&gt;, &lt;code&gt;.smart-env&lt;/code&gt;, &lt;code&gt;.trash&lt;/code&gt;, or &lt;code&gt;.git&lt;/code&gt; folder. If any of them is an actual note, stop and diff it against the original, because that is a real edit of yours that lost a race.&lt;/p&gt;

&lt;p&gt;Then, once you are sure, delete only what is inside those folders rather than everything that matched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ~/Dropbox/Apps/remotely-save &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="se"&gt;\(&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"*/.obsidian/*"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"*/.smart-env/*"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"*/.git/*"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"*/.trash/*"&lt;/span&gt; &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*conflicted copy*"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-delete&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Quit Obsidian on every device first. Otherwise a running instance rewrites its cache mid-delete and you get to do it again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwxypzd53bbf9rcd5738.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwxypzd53bbf9rcd5738.jpg" alt="Frequently Asked Questions" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you use Dropbox with Obsidian?&lt;/strong&gt; Yes. On desktop it needs no plugin at all: put the vault in your Dropbox folder and install Dropbox on both computers. On mobile you need Remotely Save or, on Android with a device-storage vault, a folder-sync app like Dropsync.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Obsidian Sync better than Dropbox?&lt;/strong&gt; It handles conflicts better and it is the only one that understands notes rather than bytes. Dropbox is better on file size, storage, and cost if you already subscribe. If you write on two devices simultaneously, pay for Sync. If you do not, Dropbox has been fine for me for years.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I sync Obsidian with Dropbox on iPhone?&lt;/strong&gt; Install Remotely Save from the community plugins browser, choose Dropbox, hit Auth, and approve. The Dropbox iOS app cannot do it on its own, because it does not sync folders to the device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Obsidian work with Dropbox on Android?&lt;/strong&gt; Yes, two ways. If the vault is in device storage, Dropsync or FolderSync does real two-way folder sync. If it is in app storage, no outside app can reach the vault, so use Remotely Save.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will Dropbox corrupt my Obsidian vault?&lt;/strong&gt; In my experience it has never touched a note. It does fork plugin caches and workspace files constantly, which produces thousands of junk files and can quietly blow past the free tier. The fix is the ignore attribute, not a different sync tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need Dropbox Plus for Obsidian?&lt;/strong&gt; Not for the notes. 2,727 of mine are 67.5 MB total. You need it if your vault carries big attachments, git history, or an AI plugin cache, and the cheaper answer there is to exclude those from sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Tell Someone Starting Today
&lt;/h2&gt;

&lt;p&gt;Put the vault in &lt;code&gt;Dropbox/Apps/remotely-save/YourVault&lt;/code&gt; on day one, before you have a phone copy to reconcile. Ignore the caches on every machine before they generate three years of garbage. Keep the folder local, never online-only. Do not also run git on it, which I say as a person still doing exactly that.&lt;/p&gt;

&lt;p&gt;Then stop thinking about it. Dropbox is not the best sync engine for Obsidian, because it is a general-purpose file syncer with no idea what a wikilink is. But Dropbox is already installed, already paid for, already running, and the failure mode is 6,517 junk files instead of a lost draft.&lt;/p&gt;

&lt;p&gt;I will take that trade. I have been taking it since 2023.&lt;/p&gt;

</description>
      <category>obsidian</category>
      <category>dropbox</category>
      <category>sync</category>
    </item>
    <item>
      <title>What to Do When Your AI Coding Agent Can't Read a Web Page</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Wed, 02 Sep 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/what-to-do-when-your-ai-coding-agent-cant-read-a-web-page-2f0i</link>
      <guid>https://dev.to/eristoddle/what-to-do-when-your-ai-coding-agent-cant-read-a-web-page-2f0i</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbqzg0bn8iaxwf4k1ktlv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbqzg0bn8iaxwf4k1ktlv.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/eristoddle/agent-skills" rel="noopener noreferrer"&gt;&lt;code&gt;fetch-anything&lt;/code&gt;&lt;/a&gt; to be stubborn. It is &lt;a href="https://dev.to/eristoddle/the-agent-skills-guide-i-wish-id-had-17i1"&gt;a skill my coding agent loads&lt;/a&gt; when it needs a web page and the built-in WebFetch tool comes back empty: when a page refuses to be read, do not give up, climb to a more aggressive tool and try again. Four rungs deep if that’s what it takes. No excuses.&lt;/p&gt;

&lt;p&gt;It worked. It also spent months doing something I hadn’t designed it to do. I had built a test harness instead of a tool and learned I should be checking what my skills are really doing more often.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Web Fetch Fallback Ladder I Built
&lt;/h2&gt;

&lt;p&gt;The ordering rule was start with the tool that burns the fewest tokens and takes the least time, and only climb when a rung fails, which the skill decides by pattern matching the response for the usual tells.&lt;/p&gt;

&lt;p&gt;Four rungs, in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;defuddle&lt;/strong&gt; strips a page down to its readable article and hands back markdown. No browser, nearly free, and it works on more of the web than you would guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;crawl4ai&lt;/strong&gt; drives a real stealth browser, so it renders JavaScript and survives the bot checks that flatten the first rung.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;playwright-cli&lt;/strong&gt; , a full scriptable browser, for when a page needs something clicked or waited on before the content exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;browser-act&lt;/strong&gt; , the heavy artillery: anti-detection browser, captcha solving, proxies, persistent sessions, and a hand-the-user-the-wheel mode for the pages that beat everything else.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Underneath these sat a small set of per-domain handlers, hardcoded knowledge for sites where the standard approach is wrong. &lt;a href="https://dev.to/eristoddle/building-a-cost-saving-agent-skill-that-accidentally-became-its-own-weekly-blog-post-3o1h"&gt;Reddit is the obvious one&lt;/a&gt;, where you fetch &lt;code&gt;old.reddit.com&lt;/code&gt; instead of even fighting the new site and move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  When WebFetch Gives Up
&lt;/h2&gt;

&lt;p&gt;When I am scraping on purpose, I have patience for a page that fights back. Fighting back is the job I signed up for when I chose the work. I am already thinking about headers and rate limits and rendering, and a hard page is just the lay of the land.&lt;/p&gt;

&lt;p&gt;The case this skill exists for is different. I need information from one page. The page decides I am a robot and shows me nothing. And now I am not doing my work anymore, I am doing scraping work, which I did not sign up for.&lt;/p&gt;

&lt;p&gt;Before the skill, my move was &lt;a href="https://dev.to/eristoddle/obsidians-new-web-clipper-youll-want-to-try-it-4ifp"&gt;the Obsidian Web Clipper&lt;/a&gt;. Open the page in a browser, clip it, drop the file into the project, tell the agent to read the file. It works every single time. It also is an easy way to break your flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fozk3vdua0iloc0zg9ega.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fozk3vdua0iloc0zg9ega.jpg" alt="When WebFetch Gives Up" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other thing is I had accumulated a pile of half-working tools, each one covering some slice of the problem, none of them the answer. I wanted one skill to use. If that one place could not get the page, fine, I would go back to clipping it by hand. But I should not have to remember which of four things to try.&lt;/p&gt;

&lt;p&gt;Get the content off the page. Hand it back as markdown, main content only. Not HTML, because a page of raw markup landing in a context window is how a cheap task turns into an expensive one, and the whole point was to spend less attention on this, not more.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Went Looking for the Numbers
&lt;/h2&gt;

&lt;p&gt;Writing this post, I decided I should prove it. My agent keeps &lt;a href="https://dev.to/eristoddle/planning-is-cheaper-than-coding-and-my-own-logs-proved-me-wrong-about-why-51bh"&gt;a session log for every conversation&lt;/a&gt;, and the ladder runs as ordinary commands inside those logs. So the evidence was sitting on my own disk. I wrote a scanner, pointed it at 187 sessions, and waited for a nice table of success rates per rung.&lt;/p&gt;

&lt;p&gt;In that same month, the full ladder ran 29 times against 416 plain fetches that never needed it. The ones that did need something extra stopped at crawl4ai.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;browser-act&lt;/code&gt;, rung four, was invoked zero times.&lt;/strong&gt; Not rarely. Zero. The only commands in the entire corpus that contain the string &lt;code&gt;browser-act&lt;/code&gt; are the searches I ran while writing this post.&lt;/p&gt;

&lt;p&gt;Go back and look at what that rung was called in the shipped source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Step 5 — Rung 5: browser-act (UNTESTED — last resort before debug-research)

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

&lt;/div&gt;



&lt;p&gt;I labeled it untested, in its own heading, and shipped it anyway. Then it sat at the bottom of the ladder for two months and never ran. It did not need a success rate. There was nothing to compute.&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Ladder: Defuddle, Crawl4AI, and Firecrawl
&lt;/h2&gt;

&lt;p&gt;Four rungs became three. Here is what happened to each one:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Old ladder&lt;/th&gt;
&lt;th&gt;What happened to it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. defuddle&lt;/td&gt;
&lt;td&gt;Kept, still rung 1. Cheapest thing that frequently just works.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. crawl4ai&lt;/td&gt;
&lt;td&gt;Kept and promoted to rung 2. The workhorse, and where the real success rate lives.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. playwright-cli&lt;/td&gt;
&lt;td&gt;Pulled out of the ladder. Still available to the debug step.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. browser-act&lt;/td&gt;
&lt;td&gt;Pulled out of the ladder. Still available to the debug step.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firecrawl&lt;/td&gt;
&lt;td&gt;New. Added as rung 3, the paid backstop.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;“I deleted a rung” is the wrong summary: the stubbornness did not go anywhere. Rule one of the skill still says a fetch is never impossible, and “this page can’t be scraped” is still defined as a bug rather than a fact. Playwright and browser-act are still in the skill, in case I need to debug what happened.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskf7vuzkazmgt55pbxfy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskf7vuzkazmgt55pbxfy.jpg" alt="The New Ladder: Defuddle, Crawl4AI, and Firecrawl" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They used to run by rote. The ladder reached them because the page was still failing, which is not a reason, it is just an ordinal. Now they sit in a separate debug step that only starts after the ladder is exhausted, and that step diagnoses the page first and picks a tool to match. Same tools, same refusal to give up. The difference is that guessing got confined to the place where guessing is the actual job.&lt;/p&gt;

&lt;p&gt;Playwright earned its demotion on the same criterion. It is a good tool for building and testing sites, and I still use it for exactly that, but for getting text off a page it is clunky, and clunky is the specific thing this skill exists to eliminate. It also has two faces. Driven through &lt;a href="https://dev.to/eristoddle/claude-mcps-vibe-coding-without-specialized-ides-part-1-1hmd"&gt;its MCP server&lt;/a&gt;, a browser window pops up in my face, and I am watching a machine use a computer instead of doing my own work. Maybe there is a setting for that. I am tired of dicking with settings. Driven through the CLI it runs in the background, gets what it came for, and never asks for my attention. A tool that interrupts me has to earn the interruption, and a fetch I only needed because I was busy with something else can never earn it.&lt;/p&gt;

&lt;p&gt;The ladder got shorter because the answer was known. And Firecrawl may not get hit for days or months, but it will be there waiting as the final rung and is almost guaranteed to work, or so they say.&lt;/p&gt;

&lt;h2&gt;
  
  
  Firecrawl at the Bottom
&lt;/h2&gt;

&lt;p&gt;Running &lt;code&gt;firecrawl config&lt;/code&gt; printed &lt;code&gt;Status: ✓ Authenticated&lt;/code&gt; and then, on the very next line, &lt;code&gt;API Key: Not set&lt;/code&gt;. Both statements were rendered with total confidence. If you hit the same thing, the key lives in &lt;code&gt;FIRECRAWL_API_KEY&lt;/code&gt;, and if you are on fish, the command you want is &lt;code&gt;set -Ux FIRECRAWL_API_KEY fc-...&lt;/code&gt;, with the &lt;code&gt;-U&lt;/code&gt;, because the session-only version evaporates the moment you close the terminal and you will be back here in ten minutes wondering why.&lt;/p&gt;

&lt;p&gt;That was the hard part of setup. The new rung 3 is &lt;a href="https://firecrawl.link/stephan-miller" rel="noopener noreferrer"&gt;Firecrawl&lt;/a&gt;, which is a hosted scraping API that handles the rendering, the rotation, and the blocking on somebody else’s machine and hands back markdown. It costs money per call, which is precisely why it belongs at the bottom.&lt;/p&gt;

&lt;p&gt;So it is worth being specific about the actual exposure. The &lt;a href="https://firecrawl.link/stephan-miller" rel="noopener noreferrer"&gt;free tier&lt;/a&gt; is a thousand pages a month, and the interesting thing about that number is not its size, it is what it tells you about how the service expects to be used. A thousand is nothing if you are crawling. But this skill never crawls anything. It fetches the one page I asked for, and only after two free rungs have already failed on that exact page, which is a small fraction of an already small number. To get near a thousand of those in a month I would have to be using the tool for something other than what I built it for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fby6ccd2twubfjxf5ayrw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fby6ccd2twubfjxf5ayrw.jpg" alt="Firecrawl at the Bottom" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the honest description of rung 3 is not “the paid one.” It is the rung that would start costing money if my habits changed a lot, and until then is just the thing that makes the failures stop. Sign up, put the key in your environment, forget it exists.&lt;/p&gt;

&lt;p&gt;I drive it through the CLI rather than its MCP server, and that is deliberate. The install one-liner and &lt;code&gt;firecrawl init&lt;/code&gt; push Firecrawl’s own agent skills, and optionally its MCP server, into every editor they can detect on your machine. I did not want a vendor writing into my tooling to solve a problem that &lt;code&gt;npm install -g firecrawl-cli&lt;/code&gt; solves.&lt;/p&gt;

&lt;p&gt;The other thing I kept, untouched, is the per-domain handlers. Those were never part of the experiment. A handler is not a guess about which tool might work, it is a thing I learned about a specific site and wrote down, like knowing that &lt;code&gt;old.reddit.com&lt;/code&gt; still serves clean HTML while the modern site fights you. Reddit is the only one so far. There will be more, because some sources come up over and over, and I am happy to build a one-off for anything I am going to need a hundred times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Fallback Chain Is an Experiment
&lt;/h2&gt;

&lt;p&gt;None of this was planned. The rewrite happened just after midnight on August 1st, inside a session in another project, which has nothing to do with scraping. I needed a page, watched the thing grind, and finally noticed I had been watching it grind the same way for months. Forty minutes later it was three rungs and I went back to what I had been doing.&lt;/p&gt;

&lt;p&gt;The generalizable part is not about scraping at all. Any time you write “try A, and if that fails try B, and if that fails try C,” you have built two things whether you meant to or not. You built a fallback chain, and you built a running experiment that records which option actually resolves things. The chain is the part you designed. The experiment is the part that accumulates an answer while you get on with your life.&lt;/p&gt;

&lt;p&gt;I did not go back to see what was happening for months, and when I finally did it was by accident, and even then I only bothered to gather the evidence properly because I was writing this post.&lt;/p&gt;

&lt;p&gt;But once the experiment has returned a result, continuing to run it on every call stupid. You already paid for that certainty. Re-buying it on each use costs time and tokens and, in my case, the exact attention the tool was supposed to protect.&lt;/p&gt;

&lt;p&gt;So go read your own logs. Not for the tool that wins, that part you probably already know in your gut. Read them for the option at the bottom that has never once been the answer. Mine had a rung that never ran a single time in two months, and I had labeled it &lt;code&gt;UNTESTED&lt;/code&gt; myself, in its own heading, where I would see it every time I opened the file.&lt;/p&gt;

&lt;p&gt;I built the thing to be stubborn. It turned out stubbornness is a fine quality in a debugger and a bad one in a plan.&lt;/p&gt;

</description>
      <category>crawl4ai</category>
      <category>firecrawl</category>
    </item>
    <item>
      <title>GLM-5.3-Flash Comes for MiMo's Cheap-LLM Crown</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 01 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/glm-53-flash-comes-for-mimos-cheap-llm-crown-3160</link>
      <guid>https://dev.to/eristoddle/glm-53-flash-comes-for-mimos-cheap-llm-crown-3160</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy3hb9711a7i5wsxqcw5h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy3hb9711a7i5wsxqcw5h.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week I told you a Chinese lab built a model that got so good at hacking it scared its own makers into holding the weights back. That was GLM-5.3. The 744B flagship. The one Z.ai benched for a couple weeks of safety hardening.&lt;/p&gt;

&lt;p&gt;This week its little brother showed up and took four of the value leaderboards.&lt;/p&gt;

&lt;p&gt;I have been tracking the cheapest-good-model question every week for a while now, and for six straight cycles the answer never moved. It was MiMo v2.5 Pro. Then GLM-5.3-Flash landed on August 26, priced lower than MiMo and scoring higher on the one benchmark that actually measures whether a model can think, and the streak was over.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The six-cycle king finally got shoved off the throne&lt;/li&gt;
&lt;li&gt;The asterisk that keeps me from crowning it&lt;/li&gt;
&lt;li&gt;The Cheapskate Picks&lt;/li&gt;
&lt;li&gt;The bill always comes due&lt;/li&gt;
&lt;li&gt;What’s coming, and what’s stalling&lt;/li&gt;
&lt;li&gt;The takeaway&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The six-cycle king finally got shoved off the throne
&lt;/h2&gt;

&lt;p&gt;Here is the pattern that held from late July all the way through last week. Every time I pulled the Arena boards, computed the competitive band for each category, and sorted by price, MiMo v2.5 Pro sat at the bottom of the price column in Overall, Coding, Instruction Following, and Hard Prompts. Same $0.43 in, $0.87 out. Same “yeah it’s slow but who cares at this price” caveat. Six weeks running.&lt;/p&gt;

&lt;p&gt;MiMo won on a simple trick. Arena ratings cluster so tight at the top that dozens of models fit within 50 points of the category leader, and MiMo lived deep in that band at a fraction of the price of everything above it. It wasn’t the smartest model. It was the cheapest model that was still good enough to sit next to the expensive ones.&lt;/p&gt;

&lt;p&gt;GLM-5.3-Flash does the exact same trick, except it does it better on both axes. It’s cheaper. It’s also smarter.&lt;/p&gt;

&lt;p&gt;Here’s the money shot. On Artificial Analysis, which grades models on hard objective benchmarks instead of crowd votes, MiMo scores a 43 on the Intelligence Index. GLM-5.3-Flash scores a 57. A 57 puts it at number 4 out of 111 open-weight models, in the same neighborhood as Kimi K3 and GLM’s own 744B flagship. And it does that at $0.15 in, $0.50 out.&lt;/p&gt;

&lt;p&gt;When the cheapest-in-band model on Arena is also near the top of the capability chart on a completely different methodology, that’s two independent judges pointing at the same model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The asterisk that keeps me from crowning it
&lt;/h2&gt;

&lt;p&gt;GLM-5.3-Flash’s Arena ratings are all preliminary. Every single one. In Coding it’s sitting at rank 11 with a 1531 rating, which sounds great, until you notice that rating is built on 663 votes with a plus-or-minus of 24 points. In Overall it has 2,424 votes. In Instruction Following, 860. MiMo, by contrast, has 56,020 votes behind its Overall rating and tens of thousands in every other category.&lt;/p&gt;

&lt;p&gt;GLM-5.3-Flash is the emerging value pick. MiMo is still the established one. If you want the cheapest number on the board and you’re fine being an early tester whose vote helps firm up a rating that might wobble, take GLM-5.3-Flash. If you want the answer you can defend when the bill comes, MiMo is still sitting right there at $0.87 with fifty thousand votes vouching for it.&lt;/p&gt;

&lt;p&gt;Two more asterisks while I’m here. First, both of these value picks are slow. GLM-5.3-Flash pushes about 41.7 tokens per second and MiMo about 37, and the median for models this size is closer to 65. That matters a lot if you’re running an agent loop where latency stacks up over hundreds of calls.&lt;/p&gt;

&lt;p&gt;Second, the cheapest price you’ll see quoted for GLM-5.3-Flash is a lie with an expiration date. OpenRouter shows it at $0.075 in, $0.25 out right now. That’s a 50 percent launch promo that dies on September 9. The list price is $0.15 and $0.50.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cheapskate Picks
&lt;/h2&gt;

&lt;p&gt;The method is the same as always. Take each category leader’s Arena rating, draw a 50-point band below it, throw out anything more expensive, and whatever’s cheapest and still in the band wins. Bands this week ran from 20 models deep in Math up to 61 in Coding, so no, “the cheapest of the top 20” does not cut it. You have to pull the full band or you’ll crown the wrong model, which this newsletter has done before and isn’t about to repeat.&lt;/p&gt;

&lt;p&gt;Prices are output dollars per million tokens, since output is what dominates most real bills.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (prelim)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;-38&lt;/td&gt;
&lt;td&gt;~100x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;claude-opus-4-7-high&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (prelim)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;-21&lt;/td&gt;
&lt;td&gt;50x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;gemini-3-flash&lt;/td&gt;
&lt;td&gt;$3&lt;/td&gt;
&lt;td&gt;-47&lt;/td&gt;
&lt;td&gt;~16.7x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-high&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (prelim)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;-49&lt;/td&gt;
&lt;td&gt;50x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-high&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (prelim)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;-38&lt;/td&gt;
&lt;td&gt;50x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;claude-opus-5-max&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;gemini-3.7-flash-high (prelim)&lt;/td&gt;
&lt;td&gt;$3.57&lt;/td&gt;
&lt;td&gt;-12&lt;/td&gt;
&lt;td&gt;~7x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few things worth saying out loud about that table.&lt;/p&gt;

&lt;p&gt;The Coding row is the wild one. GLM-5.3-Flash is only 21 rating points behind the best coding model on the planet, and it costs one fiftieth as much. If those 663 votes hold up, that’s not a value pick, that’s a heist. If you’d rather trust votes, MiMo is at $0.87 in the same band with 15,413 of them, and hy3 from Tencent is at $0.53 with 1,813. Take your pick of cheap.&lt;/p&gt;

&lt;p&gt;Creative Writing stays out of the GLM story entirely. GLM-5.3-Flash didn’t even make the band there. The Gemini Flash line still owns creative value, with plain old gemini-3-flash at $3 and a healthy 4,622 votes. Google’s Flash prices bounce around week to week like a rental car company, so always re-check them, but for now that’s your pick.&lt;/p&gt;

&lt;p&gt;Math is the category I trust least this week. The whole board is thin. The leader, Opus 5 max, is preliminary on 681 votes, and the cheapest in-band pick, gemini-3.7-flash-high at $3.57, is running on 314 votes with a plus-or-minus of 33. If you want something less wobbly, gemini-3.5-flash-high at $4.50 has 1,564 votes behind it. Neither is going to save you real money the way the GLM picks do. So is there an actual bargain hiding in Math this week? No. Sometimes a category just doesn’t have one, and Math is it right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bill always comes due
&lt;/h2&gt;

&lt;p&gt;Fortune ran a piece on August 22 about a CEO who was out to dinner when he caught one of his AI agents quietly burning through about a thousand dollars in tokens while nobody was watching. His take was that the scary part isn’t the cost, it’s the “insecurity,” his word for an agent that can’t tell it’s stuck in a loop and will happily thrash forever because it has no idea it’s failing. That rhymes with everything else I’ve read this year. Uber reportedly torched its entire annual AI coding budget in four months and capped its engineers at $1,500 a month. Amazon supposedly spent half a billion dollars in a single month after it handed out access with no caps at all.&lt;/p&gt;

&lt;p&gt;This is the context that makes a $0.50 model interesting instead of just cheap. When your agent might loop for a weekend unsupervised, the difference between $0.50 and $50 per million tokens is the difference between an annoying bill and a company-wide incident.&lt;/p&gt;

&lt;p&gt;One more gotcha, and this one is pure naming nonsense. “Flash” used to mean something specific in GLM land. The old hierarchy went Full, then Air, then Flash, with Flash being the trimmed-down budget runt of the family. GLM-5.3-Flash breaks that rule completely. It is not a shrunk version of the 744B flagship. It’s a separate model built on a new base with a different architecture, and the r/LocalLLaMA crowd spent a good chunk of launch day untangling that confusion. So if you assumed “Flash” meant “the dumb cheap one,” you were wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming, and what’s stalling
&lt;/h2&gt;

&lt;p&gt;The frontier, meanwhile, is weirdly quiet, and the quiet is all coming from the American labs.&lt;/p&gt;

&lt;p&gt;Grok 4.7 is the big pending item. It’s a 2.1 trillion parameter model that xAI has been training with supplemental SpaceX data, and Musk said on August 12 it needed “three to four weeks,” which would have put it in early September. It’s slipping. Training is reportedly done, the release keeps sliding, and I’ll believe it when it’s on a leaderboard.&lt;/p&gt;

&lt;p&gt;Gemini 3.5 Pro is, for all practical purposes, dead. Google missed date after date on it, and the word now is that they’ve shelved it and pivoted straight to pretraining Gemini 4, which they’ve publicly confirmed is a full new foundation model. Prediction markets give Gemini 4 something like an 85 percent chance of shipping by the end of November. In the meantime the 3.6 and 3.7 Flash models are Google’s actual working flagships, which is a strange place for the company to be.&lt;/p&gt;

&lt;p&gt;And the GLM-5.3 story from last week got its ending. After the two-week safety delay, Z.ai did release the full 744B flagship weights on Hugging Face around August 28. So both halves of the family are now out in the open. The flagship you’ll need roughly eight GPUs to run, and the Flash you can rent for a nickel. Guess which one more people will actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Six weeks of “the answer is still MiMo” and then the answer changed, which is the most interesting thing that’s happened in the value tier since I started tracking it. GLM-5.3-Flash is cheaper and smarter than the model that held the crown for a month and a half, and it’s the open-weight sibling of a flagship that got benched for being too dangerous. That’s a hell of a family.&lt;/p&gt;

&lt;p&gt;But I’m not going to sit here and tell you the streak is definitively over on 663 votes. What I’ll tell you is this. If you’re already paying MiMo prices for a workload where a wrong answer costs you an annoyed shrug instead of a lawsuit, go throw some traffic at GLM-5.3-Flash and help firm up those ratings. If you need the safe answer today, MiMo hasn’t gotten worse, it just got company. Either way, quote the list price, not the promo, and remember that both of them are slow enough to matter if you’re running them in a loop.&lt;/p&gt;

&lt;p&gt;Check back next week. If GLM-5.3-Flash is still cheapest-in-band with a few thousand more votes under it, we’ll call the reign officially over. If it wobbles back out of the band, well, MiMo will be right where it always is, at the bottom of the price column, being boring and cheap and good enough. I could do worse than a king like that.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
    </item>
    <item>
      <title>The Other Doc Got Fat Too: My Task File Was 90% Finished Work</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 27 Aug 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/the-other-doc-got-fat-too-my-task-file-was-90-finished-work-4hjc</link>
      <guid>https://dev.to/eristoddle/the-other-doc-got-fat-too-my-task-file-was-90-finished-work-4hjc</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fehbvt3lig37zsu5b3nbv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fehbvt3lig37zsu5b3nbv.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A month ago I wrote about my &lt;a href="https://dev.to/eristoddle/the-living-plan-got-fat-compacting-a-doc-that-wont-stop-growing-3nk0"&gt;living PLAN.md getting fat&lt;/a&gt; and the skill I built so I’d never have to compact it by hand again. 28,357 words down to 8,332. I was pleased with myself. I wrote a whole section called “It’s a Process” about how this is maintenance, not a one-time fix, and then I went right back to not thinking about it.&lt;/p&gt;

&lt;p&gt;Two weeks ago I was working on the supplement wiki project and typed something at Claude that I’d been thinking for a while: &lt;strong&gt;the tasks file is huge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It was 758 lines. About 686 of them were work that was already finished. And every one of those lines &lt;a href="https://dev.to/eristoddle/somebody-finally-wrote-down-why-my-coding-agents-keep-failing-the-same-way-13o"&gt;gets handed to the agent at the start of every session&lt;/a&gt; whether anyone is reading it or not.&lt;/p&gt;

&lt;p&gt;And the skill I’d built for exactly this problem had no idea what to do with it, because I had only ever taught it about the other file. The &lt;a href="https://github.com/eristoddle/agent-skills" rel="noopener noreferrer"&gt;living-plan skill&lt;/a&gt;, which I built to keep a project’s &lt;code&gt;PLAN.md&lt;/code&gt; and &lt;code&gt;TASKS.md&lt;/code&gt; small enough to actually load every session, knew how to cool a bloated &lt;code&gt;PLAN.md&lt;/code&gt;. Point it at a bloated &lt;code&gt;TASKS.md&lt;/code&gt; and it would happily apply the wrong medicine, because I had never noticed these are two different diseases. (The skill used to be called &lt;code&gt;plan-rebalance&lt;/code&gt;. It isn’t anymore, and this post is part of why.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two Files, Two Completely Different Ways to Get Fat&lt;/li&gt;
&lt;li&gt;The Tell: A File That Contradicts Itself&lt;/li&gt;
&lt;li&gt;The Eviction Rule (and Why It Can’t Be Automatic)&lt;/li&gt;
&lt;li&gt;The Two Carve-Outs, or How I Nearly Threw Away the Good Part&lt;/li&gt;
&lt;li&gt;Move It With sed, Not With Your Hands&lt;/li&gt;
&lt;li&gt;What 758 Lines Looks Like at 100&lt;/li&gt;
&lt;li&gt;Fix the File, Then Fix the Rule That Let It Happen&lt;/li&gt;
&lt;li&gt;One More Thing Before the Confession&lt;/li&gt;
&lt;li&gt;To Be Honest&lt;/li&gt;
&lt;li&gt;What’s Next&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Two Files, Two Completely Different Ways to Get Fat
&lt;/h2&gt;

&lt;p&gt;If you haven’t read &lt;a href="https://dev.to/eristoddle/my-third-try-how-a-living-plan-beat-both-vibe-coding-and-spec-kit-5a89"&gt;the first post&lt;/a&gt;, the setup is: one &lt;code&gt;PLAN.md&lt;/code&gt; holds decisions, open questions, and a session log, and one &lt;code&gt;TASKS.md&lt;/code&gt; holds the current batch of committed work that an implementer agent actually executes. &lt;a href="https://dev.to/eristoddle/the-expensive-model-only-plans-now-i-split-my-ai-coding-rig-across-two-tools-4dch"&gt;Planner writes the first one. Executor writes the second.&lt;/a&gt; The skill that owns both docs is open source now, in my &lt;a href="https://github.com/eristoddle/agent-skills" rel="noopener noreferrer"&gt;agent-skills repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PLAN.md&lt;/code&gt; bloats because &lt;strong&gt;decisions accumulate.&lt;/strong&gt; Every architectural call gets appended, forever, and the fix is what I call cooling: figure out what nothing active references anymore, move the body out of the main doc into &lt;code&gt;docs/&lt;/code&gt;, leave a one-line pointer behind. Reference plus a foundational flag, not recency, because an old load-bearing decision is rarely mentioned and would get wrongly archived by a recency test.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TASKS.md&lt;/code&gt; bloats for a reason that looks almost like the opposite. &lt;strong&gt;The discipline was working.&lt;/strong&gt; The rule in my &lt;code&gt;AGENTS.md&lt;/code&gt; said: flip each piece’s checkbox as it completes, and when the whole queue is done, collapse it to one summary block under a stable &lt;code&gt;[tag]&lt;/code&gt;. Both of those happened. The file was full of neat, correctly collapsed, correctly tagged blocks of finished work.&lt;/p&gt;

&lt;p&gt;They just never left.&lt;/p&gt;

&lt;p&gt;Check, collapse, evict. I had built two stages of a three-stage rule and called it a discipline. A collapse-only rule doesn’t stop a file from growing without bound. It just makes the growth tidy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq25qwkvwzg386bb15042.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq25qwkvwzg386bb15042.jpg" alt="Two Files, Two Completely Different Ways to Get Fat" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the skill got a new route instead of a shared one, and the detect step now measures both files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# size proxy for both docs (NOT live context %, which the agent can't read reliably)&lt;/span&gt;
&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; PLAN.md TASKS.md 2&amp;gt;/dev/null
&lt;span class="c"&gt;# how much of the task doc is already finished?&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'^\s*-\s*\[x\]'&lt;/span&gt; TASKS.md 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'^\s*-\s*\[\]'&lt;/span&gt; TASKS.md 2&amp;gt;/dev/null

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

&lt;/div&gt;



&lt;p&gt;That second line is the actual change in thinking. For &lt;code&gt;PLAN.md&lt;/code&gt; the nudge is a word count, defaulting to 15,000. For &lt;code&gt;TASKS.md&lt;/code&gt; a word count tells you nothing useful, because a task file can be legitimately long during a big batch. The signal is a &lt;strong&gt;ratio&lt;/strong&gt; : when finished material is over roughly 60% of the file, say so out loud. “TASKS.md is 758 lines, about 90% of it completed work” is a sentence that justifies surgery. “TASKS.md is 9,000 words” isn’t.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tell: A File That Contradicts Itself
&lt;/h2&gt;

&lt;p&gt;Here’s the diagnostic step I’d never have thought to write down if I hadn’t hit it: &lt;strong&gt;look for the file arguing with itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The strongest evidence a doc has stopped being read is that it contains two statements that can’t both be true. In this file, the deferred-work queue listed a research pass as upcoming. The status header, about thirty lines further up, said that same pass had completed two months earlier.&lt;/p&gt;

&lt;p&gt;Those entries don’t get archived. They get &lt;strong&gt;deleted.&lt;/strong&gt; Archiving a lie just relocates the lie somewhere I’m even less likely to read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Eviction Rule (and Why It Can’t Be Automatic)
&lt;/h2&gt;

&lt;p&gt;A collapsed block leaves &lt;code&gt;TASKS.md&lt;/code&gt; when &lt;strong&gt;both&lt;/strong&gt; of these hold:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Every task in the block is checked off.&lt;/strong&gt; If one task in it is still open, the block can’t move as a unit. Split it: the finished tasks move out, the open one gets promoted to its own live item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing still open points at it.&lt;/strong&gt; An open item that says “see the FIX-6 notes” pins those notes in place until it’s either resolved or rewritten to point at the archive.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The obvious next thought is to fire this automatically when a queue drains. Don’t. Two reasons, and the second one took me a minute to see.&lt;/p&gt;

&lt;p&gt;Condition 2 is a judgment call. “Does anything still open depend on this” is a question about intent, and it lives in the planning thread, not in a grep.&lt;/p&gt;

&lt;p&gt;And the implementer agent must never do this while it’s working, because &lt;strong&gt;it would be editing the file that holds its own run state.&lt;/strong&gt; &lt;code&gt;TASKS.md&lt;/code&gt; is where the executor logs which piece it’s on and &lt;a href="https://dev.to/eristoddle/the-bottleneck-was-me-how-i-stopped-racing-my-ai-builder-and-started-pacing-it-3e1n"&gt;whether it stopped clean or blocked&lt;/a&gt;. That’s the recovery record for a killed session. An agent that relocates half of that file mid-run is sawing the branch it’s standing on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1swb82s72mfwwdx80jvd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1swb82s72mfwwdx80jvd.jpg" alt="The Eviction Rule (and Why It Can't Be Automatic)" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What never leaves, no matter how big the file gets: open checkboxes, the open-items list, the deferred and pre-launch queues, the active queue and its run-state note, and the status header.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Carve-Outs, or How I Nearly Threw Away the Good Part
&lt;/h2&gt;

&lt;p&gt;“Move the finished stuff to an archive” sounds complete. It isn’t, because some of what’s buried in a finished block isn’t history at all. It’s operational knowledge that the &lt;em&gt;next&lt;/em&gt; pass needs, and dropping it into an archive nobody opens is a silent loss. It looks tidy. It’s data destruction with good manners.&lt;/p&gt;

&lt;p&gt;Two things get lifted out before anything moves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carve-out 1: reusable lessons.&lt;/strong&gt; The test is one question. &lt;em&gt;Would the next person doing a similar pass need this?&lt;/em&gt; If yes, it’s a lesson, not history. Out of those done blocks came 112 lines of stuff like the project’s canonical three-part definition of done, and the blunt note that Amazon is dead as a prose source. None of that is a record of what happened. All of it is what to do next time. It went to &lt;code&gt;docs/references/lessons.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carve-out 2: artifact inventory.&lt;/strong&gt; I found that the collapsed done blocks were the only place recording which backfill scripts existed and what each one did. That’s not a task log, that’s documentation that had accidentally been filed under history. It became a 19-row table in &lt;code&gt;pipeline/README.md&lt;/code&gt;, next to the code, where somebody might actually find it.&lt;/p&gt;

&lt;p&gt;Everything else moves verbatim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Move It With sed, Not With Your Hands
&lt;/h2&gt;

&lt;p&gt;Halfway through this run, I confidently concluded that &lt;code&gt;pipeline/README.md&lt;/code&gt; didn’t exist. It existed. It was right there. A &lt;code&gt;cd&lt;/code&gt; inside a Bash call &lt;strong&gt;persists&lt;/strong&gt; , and an earlier &lt;code&gt;cd&lt;/code&gt; into a subdirectory was silently redirecting every later relative-path check I ran. That’s twenty minutes I’m not getting back. The workflow now says to use absolute paths or re-anchor with &lt;code&gt;cd &amp;lt;root&amp;gt; &amp;amp;&amp;amp;&lt;/code&gt; on every command, and I’ve since hit the same thing in two other sessions, so apparently I needed it written down.&lt;/p&gt;

&lt;p&gt;That detour aside, the actual move: 732 lines had to relocate. There is a strong temptation to have the agent read the old file and write a nice clean new one.&lt;/p&gt;

&lt;p&gt;Don’t do that, for two reasons.&lt;/p&gt;

&lt;p&gt;The first is fidelity. That material was already collapsed once. Summarizing it again strips detail the author (me, earlier, with more context on the problem) deliberately chose to keep. Re-summarizing a summary is how a project quietly forgets things.&lt;/p&gt;

&lt;p&gt;The second is cost. Retyping 700 lines means &lt;a href="https://dev.to/eristoddle/planning-is-cheaper-than-coding-and-my-own-logs-proved-me-wrong-about-why-51bh"&gt;those 700 lines go through the model twice, in and out&lt;/a&gt;, for a job that is fundamentally &lt;code&gt;cat&lt;/code&gt;. That’s a pile of context burned to accomplish nothing but a move.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4eavtrrhbvch4fg8d90z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4eavtrrhbvch4fg8d90z.jpg" alt="Move It With sed, Not With Your Hands" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So: back the file up first, then assemble the archive by piping line ranges with &lt;code&gt;sed -n 'A,Bp'&lt;/code&gt;. Verify the seams afterward with a heading grep on the result rather than reading the whole thing back.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 758 Lines Looks Like at 100
&lt;/h2&gt;

&lt;p&gt;What survived: the status header, the blocked design pass with its visual-pass items and a note about a CSS stopgap, five open items, the deferred and post-launch queues, and an eight-row &lt;strong&gt;Done index&lt;/strong&gt;. That index is a table with one row per &lt;code&gt;[tag]&lt;/code&gt;, what it was, its dates, and a link into the archive. Eight rows replacing about 686 lines.&lt;/p&gt;

&lt;p&gt;The part I didn’t expect: the sweep &lt;strong&gt;found work.&lt;/strong&gt; Reading the file carefully enough to decide what could leave surfaced two open items that had never been tracked anywhere. A sub-piece of the symptom work that was quietly incomplete, and 74 noisy relationship edges in the graph that I’d noted in passing and then lost in the pile. Both got promoted to live open items instead of being archived with the block they were buried in.&lt;/p&gt;

&lt;p&gt;Which is its own argument for doing this. A file too big to re-read isn’t just heavy. It’s actively hiding things from you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix the File, Then Fix the Rule That Let It Happen
&lt;/h2&gt;

&lt;p&gt;The bloat wasn’t drift. It wasn’t the agent misbehaving. It was a &lt;strong&gt;rule with a missing stage.&lt;/strong&gt; Process Rule 3 in &lt;code&gt;AGENTS.md&lt;/code&gt; said check, then collapse, and stopped. The agent followed it perfectly. Fixing only the file guarantees you’ll be doing this again in six weeks with more lines.&lt;/p&gt;

&lt;p&gt;So the rule got rewritten to state all three stages explicitly, with the eviction gate spelled out, both carve-outs named with their destination files, and an explicit “what never leaves” list. Then &lt;a href="https://dev.to/eristoddle/the-agent-skills-guide-i-wish-id-had-17i1"&gt;the skill got the new route&lt;/a&gt; and the &lt;code&gt;workflows/evict-tasks.md&lt;/code&gt; file, the docs index got the two new files, and the run went into the ledger with its dates and line counts so the next run doesn’t re-derive any of this.&lt;/p&gt;

&lt;p&gt;If you rebalance a doc without changing the rule that let it bloat, you haven’t built a system. You’ve signed up for a recurring chore.&lt;/p&gt;

&lt;h2&gt;
  
  
  One More Thing Before the Confession
&lt;/h2&gt;

&lt;p&gt;Eight lines of skill, and it has nothing to do with task files. It’s about the other doc. I’m putting it here because the lesson underneath it is the same one this whole post is about: what an archive promises.&lt;/p&gt;

&lt;p&gt;Cooling a decision uses reference, not recency: if nothing active points at it, the body moves to &lt;code&gt;docs/decisions/&lt;/code&gt; and a one-line pointer stays behind. There was already one marker that overrides this, &lt;code&gt;🔒 foundational&lt;/code&gt;, for load-bearing decisions that are rarely referenced but must never leave.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgsvxi6tocf28ghuj6iv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgsvxi6tocf28ghuj6iv.jpg" alt="One More Thing Before the Confession" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I hit a case the model didn’t cover. A decision can be genuinely cold by reference, nothing points at it, and still describe work that is &lt;strong&gt;decided but not built yet.&lt;/strong&gt; Cooling its body is correct. Cooling it &lt;em&gt;silently&lt;/em&gt; is not, because the decisions index is the thing I skim, and an index that reads as “here are the settled decisions” quietly implies they’re all done.&lt;/p&gt;

&lt;p&gt;So there’s a second marker now. &lt;code&gt;🔨&lt;/code&gt; on the pointer heading means decided-but-unbuilt, which makes the decisions index double as a pending-build list. &lt;code&gt;🔨&lt;/code&gt; still cools, unlike &lt;code&gt;🔒&lt;/code&gt;. It just flags status, and it comes off when the work ships. The line that settled it, from the ledger: &lt;em&gt;“if there’s a designator that says they’re unbuilt, that’s enough.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The general lesson is the same one the task file taught me. When you archive something, ask what the archive is promising. The decisions index was promising “decided” and I was reading it as “done.” The task file was promising “managed” and it meant “stored.”&lt;/p&gt;

&lt;h2&gt;
  
  
  To Be Honest
&lt;/h2&gt;

&lt;p&gt;I have run this exactly once. One project, one file, 758 lines to 100. That’s a real result and it is not a validated heuristic. The 60% ratio threshold is a number I picked because 90% was so obviously past the line that anything below it seemed safe to start at.&lt;/p&gt;

&lt;p&gt;And here’s the genuinely embarrassing part.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;content-tools-v2&lt;/code&gt; is the project whose 28,357-word &lt;code&gt;PLAN.md&lt;/code&gt; kicked off this entire series. Its &lt;code&gt;TASKS.md&lt;/code&gt; is sitting at &lt;strong&gt;1,056 lines and 10,938 words&lt;/strong&gt; as I write this. It has finished blocks from session 35, a halted block whose opening note says “do not pick this up,” and a shelved block marked superseded by decision D27, which has been sitting there since before I wrote the eviction workflow. Its &lt;code&gt;PLAN.md&lt;/code&gt; is back up to &lt;strong&gt;16,408 words&lt;/strong&gt; , which is over my own 15,000-word nudge threshold. I compacted that file to 8,332 words in June and to 4,700 on July 1st.&lt;/p&gt;

&lt;p&gt;So I built the workflow on a different project, it cut 87% off a real file, and I have not run it on the repo that most obviously needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;Run it on content-tools-v2, obviously, and find out whether a task file shaped by a different kind of project breaks the rule I just wrote. A halted arc and a superseded shelf are exactly the ambiguous cases the two-condition gate was supposed to handle, and I don’t fully trust it until it’s survived something it wasn’t designed against.&lt;/p&gt;

&lt;p&gt;After that, the thesis post I keep threatening to write. Planning is the only thing in the stack worth a boutique model, everything downstream is keystrokes you can buy in bulk, and the plan is only cheap to enforce if the docs holding it stay small enough to read. Which, it turns out, the docs do not do on their own.&lt;/p&gt;

</description>
      <category>agentictaskmanagemen</category>
      <category>agenticworkflowoptim</category>
      <category>agentskills</category>
      <category>agenticdevelopment</category>
    </item>
    <item>
      <title>GLM-5.3 Got Too Good at Hacking to Ship on Time</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 25 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/glm-53-got-too-good-at-hacking-to-ship-on-time-450p</link>
      <guid>https://dev.to/eristoddle/glm-53-got-too-good-at-hacking-to-ship-on-time-450p</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5hu3awlhqidtcfkh48ek.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5hu3awlhqidtcfkh48ek.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Chinese AI lab shipped a model that got so good at hacking, mid-training, that they decided to hold the open weights back and spend two more weeks hardening it before they let you download it. The model started writing full exploitation chains on its own and they got a little spooked by their own homework.&lt;/p&gt;

&lt;p&gt;That’s Z.ai’s GLM-5.3. And it is the cleanest sign yet that the interesting stuff in AI is no longer happening where it used to. The frontier is leaking into open weights.&lt;/p&gt;

&lt;p&gt;Meanwhile the cheap model I keep telling you to use won its sixth straight week as the best value on the board, Google reportedly gave up on the flagship it promised at I/O and started over, and Elon says Grok 4.7 is “3 to 4 weeks” out, which in Musk time means sometime before the heat death of the universe.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The model that outgrew its own training&lt;/li&gt;
&lt;li&gt;The cheapskate table, and why it’s boring on purpose&lt;/li&gt;
&lt;li&gt;Newest is not best, and the labs know it&lt;/li&gt;
&lt;li&gt;The token bill comes due&lt;/li&gt;
&lt;li&gt;What’s coming, and what quietly died&lt;/li&gt;
&lt;li&gt;The honest read&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The model that outgrew its own training
&lt;/h2&gt;

&lt;p&gt;GLM-5.3 came out of Z.ai on August 14. Same base model as GLM-5.2, they say. Every gain came from scaled-up post-training, which is already a slightly unnerving sentence when you read the rest of it.&lt;/p&gt;

&lt;p&gt;Here’s the part that made me put my coffee down. On CyberGym, a cybersecurity benchmark, GLM-5.3 scored 84.5%. That is the leading published number on that benchmark. It beats Claude Fable 5 (83.8%) and GPT-5.6 Sol (83.6%), which are the two most safety-gated, most lawyered, most “we take this very seriously” frontier models the West has. An open-weights model from a company most American developers can’t name just posted the best offensive-security score anyone has published.&lt;/p&gt;

&lt;p&gt;And the way Z.ai describes how it got there is the actual story. They fed the model vulnerability-discovery data expecting it to get better at finding isolated bugs. Instead, in their own words, “capability continued compounding as training scaled, and the model began reasoning across multiple stages of exploitation, forming coherent plans for complete exploitation chains rather than isolated bug-finding.”&lt;/p&gt;

&lt;p&gt;Read that again. They wanted a better bug-finder. They got something that plans whole attacks. ExploitBench doubled, from 24.4% to 54.4%. On a practical exploitation task, the old model solved 29 problems in two hours and GLM-5.3 solved 105. That is not a nudge. That is a different animal.&lt;/p&gt;

&lt;p&gt;So Z.ai is now delaying the open-weights release, which they’ve promised for “about two weeks,” specifically to harden a model they publicly admit developed offensive capability faster than they expected. Sit with the shape of that. For a year the story was: the West locks its models down, China ships open. Remember Claude Fable 5 getting yanked offline by a US export-control order back in June because a jailbreak might unlock cyber capabilities? Now a Chinese lab is voluntarily holding its own weights over the exact same fear.&lt;/p&gt;

&lt;p&gt;But every one of those cyber numbers is on Z.ai’s own evaluations. Nobody independent has replicated CyberGym at 84.5% yet. Treat it like every vendor launch table, which is to say: interested, but skeptical, until someone with no skin in it runs the eval. The exact decimal is marketing until proven otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheapskate table, and why it’s boring on purpose
&lt;/h2&gt;

&lt;p&gt;Every week I pull the Arena leaderboards, take each category leader’s rating, draw a line 50 points below it, and find the cheapest model that still sits inside that band. Not the cheapest of the top 20. The cheapest inside the whole 50-point window, because that window runs 50-plus models deep and the good cheap stuff lives way down in the ranks where nobody scrolls.&lt;/p&gt;

&lt;p&gt;I do it in code now, because I got burned eyeballing the first screen once and it’s a mistake you only make in public one time.&lt;/p&gt;

&lt;p&gt;Here is where the value actually is this week:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader (output $/1M)&lt;/th&gt;
&lt;th&gt;Cheapskate pick (output $/1M)&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;th&gt;Rating gap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;claude-fable-5 ($50)&lt;/td&gt;
&lt;td&gt;mimo-v2.5-pro ($0.87)&lt;/td&gt;
&lt;td&gt;~57x&lt;/td&gt;
&lt;td&gt;-40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;claude-opus-4-7-high ($25)&lt;/td&gt;
&lt;td&gt;mimo-v2.5-pro ($0.87)&lt;/td&gt;
&lt;td&gt;~29x&lt;/td&gt;
&lt;td&gt;-33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-fable-5 ($50)&lt;/td&gt;
&lt;td&gt;gemini-3.6-flash-high ($1.88)&lt;/td&gt;
&lt;td&gt;~27x&lt;/td&gt;
&lt;td&gt;-38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-high ($25)&lt;/td&gt;
&lt;td&gt;mimo-v2.5-pro ($0.87)&lt;/td&gt;
&lt;td&gt;~29x&lt;/td&gt;
&lt;td&gt;-43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-high ($25)&lt;/td&gt;
&lt;td&gt;mimo-v2.5-pro ($0.87)&lt;/td&gt;
&lt;td&gt;~29x&lt;/td&gt;
&lt;td&gt;-37&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;claude-opus-5-max ($25)&lt;/td&gt;
&lt;td&gt;gemini-3.6-flash-high ($1.88)&lt;/td&gt;
&lt;td&gt;~13x&lt;/td&gt;
&lt;td&gt;-35&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;MiMo v2.5 Pro from Xiaomi takes four of the six categories again. Overall, Coding, Instruction Following, Hard Prompts. Eighty-seven cents per million output tokens versus fifty dollars for the Fable 5 leader in the Overall board. That’s not a discount. That’s a different pricing universe, for a rating that lands 40 points back on a scale where the entire competitive top end fits inside 50.&lt;/p&gt;

&lt;p&gt;This is the sixth straight week MiMo has held this spine. Six weeks. If you’re waiting for me to announce some exciting new value pick, I don’t have one, and that’s the point. The honest recommendation hasn’t changed since mid-July. When you want cheap and genuinely competitive for everyday work, this is still the answer. Artificial Analysis backs it up from the other direction too: MiMo sits on their Intelligence-vs-Cost Pareto frontier, which means two totally different methodologies point at the same model. That’s about as strong a signal as this job produces.&lt;/p&gt;

&lt;p&gt;The caveats are the same ones I gave you last month, because they haven’t changed either. MiMo is slow, about 52 tokens per second, below the median. And its raw intelligence score on Artificial Analysis is 43 against a frontier around 60. So for genuinely hard reasoning, this isn’t your model. For the 90% of work that’s “summarize this, rewrite that, follow these instructions,” you will not feel the missing 40 rating points and you will very much feel the 57x price cut.&lt;/p&gt;

&lt;p&gt;Creative Writing and Math both go to Gemini 3.6 Flash-high at $1.88, same as last week. Two notes on the table. In Coding there’s a cheaper gamble sitting right at the band edge: hy3, Tencent’s Hunyuan 3, at 53 cents, two points above the cutoff line on only 1,655 votes. It undercuts MiMo but it’s riding the very edge of the band on thin data, so I keep MiMo as the anchor and file hy3 under “for people who like living dangerously.” And the Math pick is shaky: the leader there is preliminary on 592 votes and the whole band is only 12 models deep. Take it as provisional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Newest is not best, and the labs know it
&lt;/h2&gt;

&lt;p&gt;Here’s a thing that should embarrass more people than it does. On the Arena Overall board, Anthropic’s Claude Opus 4.6-high sits at #2. Its own newer sibling, Opus 5-high, sits at #7. The older model beats the newer one from the same company. Opus 5 only clearly wins Math, and that’s on preliminary votes.&lt;/p&gt;

&lt;p&gt;We have fully arrived at the era where “just use the latest one” is bad advice, and it’s bad advice inside a single lab’s own lineup. The version number went up. The blind-comparison preference went down. That happens more than the launch blog posts would ever tell you.&lt;/p&gt;

&lt;p&gt;The flip side is Grok 4.6, which is the opposite trap. On Artificial Analysis it’s up in the top cluster at 60-61, right there with Opus 5 and GPT-5.6 Sol. On Arena it’s languishing around #46 Overall on 3,400-ish fresh votes. That’s not a contradiction, it’s just Arena being slow to accumulate votes on a new model. When the hard-benchmark score and the crowd-vote score disagree this hard on a fresh release, believe the benchmark for now. Grok 4.6 is smarter than it looks in the blind booth. At $2/$6 flat, it’s also cheap for what it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The token bill comes due
&lt;/h2&gt;

&lt;p&gt;If you run agents, you already know the horror story, because you’ve either lived it or you’re one unattended weekend away from it.&lt;/p&gt;

&lt;p&gt;The numbers coming out this cycle are genuinely stupid. One company reportedly ran up something like a $500 million Claude bill after forgetting to set usage limits for employees. Uber apparently torched its entire 2026 AI-coding budget by April. Teams routinely report hitting 3x their annual token budget by spring. And the recurring nightmare, the one that’ll get you personally: a handful of agents stuck in a recursive loop, running unattended over a weekend, ringing up tens of thousands of dollars because every step re-sends the full context and every step gets billed.&lt;/p&gt;

&lt;p&gt;The mechanism never changes. An agent doesn’t make one call. It makes hundreds, in loops, across tools, while you’re asleep. The cost model of a chatbot and the cost model of an autonomous agent are not the same species, and a lot of budgets are still priced like it’s 2024.&lt;/p&gt;

&lt;p&gt;Then there’s slopsquatting, which is my new favorite piece of dystopia. LLMs hallucinate package names. Attackers noticed. So they pre-register the fake names the models invent, as malware. Your coding agent confidently runs &lt;code&gt;pip install&lt;/code&gt; on a package that didn’t exist until a bad actor created it to catch exactly this mistake. It’s a cost bug and a supply-chain attack wearing the same coat. Around one in five AI-suggested packages don’t exist, and now some of the ones that “do” are traps.&lt;/p&gt;

&lt;p&gt;And loop it back to GLM-5.3 for a second, because the dual-use thing isn’t abstract. A model that plans full exploitation chains, shipped as open weights you can run locally with no logging and no off switch, is the defensive-security teams’ entire worry expressed in a single download. The vendor said the quiet part out loud this time. That’s progress of a sort.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming, and what quietly died
&lt;/h2&gt;

&lt;p&gt;Grok 4.7 is “training done, SpaceX data going in, 3 to 4 weeks out,” per Musk, a window that already slipped from late July. Pencil in early September, and use a pencil with a good eraser. GLM-5.3’s open weights are the two-weeks-out release I mentioned above, assuming the safety hardening goes to plan. The delay is the story there, not the date.&lt;/p&gt;

&lt;p&gt;Then there’s Gemini 3.5 Pro, which is, according to SemiAnalysis, shelved. Dead. Google reportedly gave up after missing late June, then July 17, then early August, and pointed its engineers at pretraining Gemini 4 instead, the largest single training run Pichai says the company has ever attempted. So Gemini 3.6 Flash is the stopgap flagship now. That’s a strange sentence to type about a Flash model. When your fast, cheap tier is holding the fort because the real flagship got scrapped, you can guess how the pretraining bet is going. One more for the pile: GLM-5.2 Turbo shipped August 17, a speed-tuned variant, not on Arena yet. Filed for next week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest read
&lt;/h2&gt;

&lt;p&gt;I’ve been writing this roundup long enough to watch a genuine trend line form, and here it is: the capability that used to justify locking models in a vault keeps showing up in open weights you can download, mostly from China, at a fraction of the price, a few weeks later. First it was cost. Now it’s frontier-grade cyber capability. The export controls, the safety gates, the “limited release via vetted partners” stuff, all of it assumes the good models live in a few buildings you can regulate. The board says otherwise. Chinese models are about 45% of all OpenRouter traffic now, up from a world where US models were 70% a year ago.&lt;/p&gt;

&lt;p&gt;None of this is a reason to run GLM-5.3 as your daily driver, and it’s definitely not a reason to skip the boring correct answer. If you take one practical thing from this week, take the table: MiMo v2.5 Pro for the everyday grind, Gemini 3.6 Flash-high when you need creative or math on a budget, and a very short leash on any agent you let run unattended. The exciting model this week is the one that scared its own creators. The one you should actually be using is still the unglamorous 87-cent workhorse that’s won six weeks running and will probably win a seventh.&lt;/p&gt;

&lt;p&gt;See you next week, assuming an agent hasn’t bankrupted either of us by then.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
    </item>
    <item>
      <title>Claude Code on DeepSeek: In One Command</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 20 Aug 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/claude-code-on-deepseek-in-one-command-edc</link>
      <guid>https://dev.to/eristoddle/claude-code-on-deepseek-in-one-command-edc</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyn3lf2rdrer5688fdz7g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyn3lf2rdrer5688fdz7g.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve probably mentioned that I’ve been trying to stop paying Opus prices for work that does not deserve it. I &lt;a href="https://dev.to/eristoddle/the-cheapskates-guide-to-the-arena-leaderboard-why-i-stopped-paying-claude-opus-prices-1ipn"&gt;wrote a whole cheapskate’s guide about it&lt;/a&gt;, and since then I &lt;a href="https://dev.to/eristoddle/the-expensive-model-only-plans-now-i-split-my-ai-coding-rig-across-two-tools-4dch"&gt;split my rig so the expensive model only plans&lt;/a&gt; and Opencode with cheaper models does the grind. That worked. But it gave me two different tools and two different sets of muscle memory, and some nights I just want the Claude Code I already know.&lt;/p&gt;

&lt;p&gt;So when I saw a post going around with three &lt;code&gt;export&lt;/code&gt; lines that are supposed to point Claude Code at DeepSeek, I gave it a try.&lt;/p&gt;

&lt;p&gt;It did not work. It gave me an error message. And the fix was a single path segment.&lt;/p&gt;

&lt;p&gt;Here is the working version, why the copy-paste version fails, and a launcher that switches to DeepSeek models in one command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What DeepSeek Gives You&lt;/li&gt;
&lt;li&gt;The Issue That Cost Me Time&lt;/li&gt;
&lt;li&gt;Why I Did Not Just Export the Variables&lt;/li&gt;
&lt;li&gt;The Fish Function&lt;/li&gt;
&lt;li&gt;If You Don’t Use Fish&lt;/li&gt;
&lt;li&gt;The Slot Mapping, and the Problem I Invented&lt;/li&gt;
&lt;li&gt;Does It Work?&lt;/li&gt;
&lt;li&gt;What This Is For&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What DeepSeek Gives You
&lt;/h2&gt;

&lt;p&gt;Claude Code talks the Anthropic Messages API. It does not speak OpenAI-style chat completions. So pointing it at some random provider’s endpoint won’t work.&lt;/p&gt;

&lt;p&gt;What makes this trick possible is that DeepSeek runs an Anthropic-compatible endpoint. Ask the API what it will serve you instead of trusting a model name you read somewhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.deepseek.com/models &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Two models came back for me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"list"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"deepseek-v4-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"owned_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"deepseek"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"deepseek-v4-pro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"owned_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"deepseek"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;That is all you get. &lt;code&gt;deepseek-v4-flash&lt;/code&gt; is the fast cheap one, &lt;code&gt;deepseek-v4-pro&lt;/code&gt; is the heavier one. Two models is a really short list when you are used to looking at &lt;a href="https://dev.to/eristoddle/the-cheapest-model-on-the-internet-is-winning-flash-stopped-meaning-cheap-and-the-smartest-ai-e27"&gt;OpenRouter’s wall of options&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue That Cost Me Time
&lt;/h2&gt;

&lt;p&gt;The instructions I copied said to set this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://api.deepseek.com/v1"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Looks right. Every API you have ever used has a &lt;code&gt;/v1&lt;/code&gt; on it. And Claude Code starts up fine with it.&lt;/p&gt;

&lt;p&gt;Then you send a message and get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;There's an issue with the selected model (deepseek-v4-flash).
It may not exist or you may not have access to it.
Run --model to pick a different model.

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

&lt;/div&gt;



&lt;p&gt;So I checked the model. Is it a typo? Does my key have access? But the model was fine the whole time.&lt;/p&gt;

&lt;p&gt;Claude Code appends &lt;code&gt;/v1/messages&lt;/code&gt; to whatever you put in &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;. Give it a base ending in &lt;code&gt;/v1&lt;/code&gt; and it builds this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.deepseek.com/v1/v1/messages

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewhsdnnl1yhlhkhjowkn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fewhsdnnl1yhlhkhjowkn.jpg" alt="The Issue That Cost Me Time" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That 404s, Claude Code catches the failure, and it reports that your model did not work out. Wrong diagnosis, right symptom.&lt;/p&gt;

&lt;p&gt;This is documented behavior. The &lt;a href="https://code.claude.com/docs/en/model-config" rel="noopener noreferrer"&gt;model configuration docs&lt;/a&gt; say that behind a custom &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;, your provider defines the model names, so Claude Code passes any string through without validating it. It cannot tell a bad model name from a bad URL.&lt;/p&gt;

&lt;p&gt;The correct base is the Anthropic root, no version segment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://api.deepseek.com/anthropic"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;I tested it with raw curl before touching the launcher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.deepseek.com/anthropic/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"anthropic-version: 2023-06-01"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"deepseek-v4-flash","max_tokens":16,
       "messages":[{"role":"user","content":"say OK"}]}'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Real Anthropic-shaped response, thinking block and all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Did Not Just Export the Variables
&lt;/h2&gt;

&lt;p&gt;The easy way seems to be adding those exports to your shell config and be done. I did not want that.&lt;/p&gt;

&lt;p&gt;The moment &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; is set in your environment, it takes over your claude.ai login. Claude Code even tells you so on startup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⚠ claude.ai connectors are disabled because ANTHROPIC_API_KEY or another
  auth source is set and takes precedence over your claude.ai login

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

&lt;/div&gt;



&lt;p&gt;So if you export those globally, you have not added a DeepSeek option. You have replaced Claude Code. Every session, every project, forever, until you remember why and unset it. That is a great way to be confused at two in the morning next month.&lt;/p&gt;

&lt;p&gt;Instead I wanted a new command for running it this way, so when I run &lt;code&gt;claude&lt;/code&gt; I have no issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fish Function
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;fish&lt;/a&gt;, and this is one of those cases where it pays for itself. Fish autoloads any function file in &lt;code&gt;~/.config/fish/functions/&lt;/code&gt;, so saving &lt;code&gt;claude-ds.fish&lt;/code&gt; there gives me a new command. My DeepSeek key lives in a universal variable (&lt;code&gt;set -Ux DEEPSEEK_API_KEY sk-...&lt;/code&gt;), which persists across sessions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;function &lt;/span&gt;claude-ds &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"Launch Claude Code against the DeepSeek API"&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;not &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; DEEPSEEK_API_KEY&lt;span class="p"&gt;;&lt;/span&gt; or &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"claude-ds: DEEPSEEK_API_KEY is not set."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" set -Ux DEEPSEEK_API_KEY sk-..."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="k"&gt;return &lt;/span&gt;1
    end

&amp;lt;img &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/images/2026/claude-code-on-deepseek-one-command-and-the-base-u-body-2.jpg"&lt;/span&gt; &lt;span class="nv"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"The Fish Function"&lt;/span&gt; &lt;span class="nv"&gt;srcset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" /assets/resized/480/claude-code-on-deepseek-one-command-and-the-base-u-body-2.jpg 480w, /assets/resized/800/claude-code-on-deepseek-one-command-and-the-base-u-body-2.jpg 800w, /assets/resized/1400/claude-code-on-deepseek-one-command-and-the-base-u-body-2.jpg 1400w, "&lt;/span&gt; &lt;span class="nv"&gt;loading&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"lazy"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;# Claude Code appends /v1/messages, so the base must be the /anthropic&lt;/span&gt;
    &lt;span class="c"&gt;# root. NOT /v1, that yields /v1/v1/messages and 404s.&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; base_url &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; DEEPSEEK_BASE_URL&lt;span class="p"&gt;;&lt;/span&gt; and &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$DEEPSEEK_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        or &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"https://api.deepseek.com/anthropic"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; model_pro &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; DEEPSEEK_OPUS_MODEL&lt;span class="p"&gt;;&lt;/span&gt; and &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$DEEPSEEK_OPUS_MODEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        or &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deepseek-v4-pro"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; model_flash &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; DEEPSEEK_SONNET_MODEL&lt;span class="p"&gt;;&lt;/span&gt; and &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$DEEPSEEK_SONNET_MODEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        or &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deepseek-v4-flash"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    switch &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$argv&lt;/span&gt;&lt;span class="s2"&gt;[1]"&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nt"&gt;--ds-info&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"base url : &lt;/span&gt;&lt;span class="nv"&gt;$base_url&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"opus -&amp;gt; : &lt;/span&gt;&lt;span class="nv"&gt;$model_pro&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"sonnet-&amp;gt; : &lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"haiku -&amp;gt; : &lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;return &lt;/span&gt;0
    end

    &lt;span class="c"&gt;# `env` scopes these to the child only. Nothing leaks into this shell.&lt;/span&gt;
    &lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$base_url&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_OPUS_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_pro&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_SONNET_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_HAIKU_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_FABLE_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;ANTHROPIC_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;CLAUDE_CODE_SUBAGENT_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"inherit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        claude &lt;span class="nv"&gt;$argv&lt;/span&gt;
end

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

&lt;/div&gt;



&lt;p&gt;Those variables at the bottom get set on the child process only. When Claude Code exits, they are gone. &lt;code&gt;claude&lt;/code&gt; on its own is completely untouched.&lt;/p&gt;

&lt;p&gt;Save the file, and it works immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude-ds &lt;span class="c"&gt;# interactive, on DeepSeek&lt;/span&gt;
claude-ds &lt;span class="nt"&gt;--model&lt;/span&gt; opus &lt;span class="c"&gt;# routes to deepseek-v4-pro&lt;/span&gt;
claude-ds &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"..."&lt;/span&gt; &lt;span class="nt"&gt;--resume&lt;/span&gt; &lt;span class="c"&gt;# any normal claude flag passes straight through&lt;/span&gt;
claude-ds &lt;span class="nt"&gt;--ds-info&lt;/span&gt; &lt;span class="c"&gt;# show the mapping it will use&lt;/span&gt;
claude &lt;span class="c"&gt;# unchanged, still Anthropic&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Because everything after the flag check goes into &lt;code&gt;claude $argv&lt;/code&gt;, every flag you already know still works in this hacked DeepSeek version.&lt;/p&gt;

&lt;h2&gt;
  
  
  If You Don’t Use Fish
&lt;/h2&gt;

&lt;p&gt;Most people don’t, and a shell change is not a casual afternoon. The same thing in bash or zsh is barely longer. Drop this in &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude-ds&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"claude-ds: DEEPSEEK_API_KEY is not set."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" export DEEPSEEK_API_KEY=sk-..."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="k"&gt;return &lt;/span&gt;1
  &lt;span class="k"&gt;fi

  &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEEPSEEK_BASE_URL&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;https&lt;/span&gt;://api.deepseek.com/anthropic&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;model_pro&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEEPSEEK_OPUS_MODEL&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;deepseek&lt;/span&gt;&lt;span class="p"&gt;-v4-pro&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;model_flash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEEPSEEK_SONNET_MODEL&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;deepseek&lt;/span&gt;&lt;span class="p"&gt;-v4-flash&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"--ds-info"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'base url : %s\nopus -&amp;gt; : %s\nsonnet-&amp;gt; : %s\nhaiku -&amp;gt; : %s\n'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$base_url&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_pro&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;0
  &lt;span class="k"&gt;fi

  &lt;/span&gt;&lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$base_url&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_OPUS_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_pro&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_SONNET_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_HAIKU_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_DEFAULT_FABLE_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model_flash&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ANTHROPIC_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;CLAUDE_CODE_SUBAGENT_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"inherit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    claude &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;source ~/.zshrc&lt;/code&gt; and you have the same command. Same guarantee that plain &lt;code&gt;claude&lt;/code&gt; is untouched.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Slot Mapping, and the Problem I Invented
&lt;/h2&gt;

&lt;p&gt;Claude Code has slots for models. The &lt;code&gt;opus&lt;/code&gt;, &lt;code&gt;sonnet&lt;/code&gt;, &lt;code&gt;haiku&lt;/code&gt;, and &lt;code&gt;fable&lt;/code&gt; aliases each resolve through their own &lt;code&gt;ANTHROPIC_DEFAULT_*_MODEL&lt;/code&gt; variable. Haiku’s slot is also what background functionality runs on, so it fires constantly even when you never type &lt;code&gt;haiku&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I mapped every slot just in case. Then I tested it, and discovered I did not need to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F49sle5fks3x5emxaytm8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F49sle5fks3x5emxaytm8.jpg" alt="claude-fable-5 =&gt; responded as deepseek-v4-flash" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# claude-haiku-4-5-20251001 =&amp;gt; responded as deepseek-v4-flash
# claude-sonnet-4-5-20250929 =&amp;gt; responded as deepseek-v4-flash
# claude-opus-4-1-20250805 =&amp;gt; responded as deepseek-v4-pro
# claude-fable-5 =&amp;gt; responded as deepseek-v4-flash

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

&lt;/div&gt;



&lt;p&gt;DeepSeek’s endpoint maps Claude model names server side. Send it any &lt;code&gt;claude-opus-*&lt;/code&gt; ID and it answers as &lt;code&gt;deepseek-v4-pro&lt;/code&gt;. Send it anything else in the Claude family and you get &lt;code&gt;deepseek-v4-flash&lt;/code&gt;. So the failure I was prepping for does not happen.&lt;/p&gt;

&lt;p&gt;Send it something unknown and the error is helpful, which is more than Claude Code managed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"The supported API model names are deepseek-v4-pro or
deepseek-v4-flash, but you passed totally-not-a-model."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;I kept the explicit mapping anyway, because I would rather decide which DeepSeek model each alias hits. It also means &lt;code&gt;/model&lt;/code&gt; in the UI shows me &lt;code&gt;deepseek-v4-pro&lt;/code&gt; instead of a Claude name that is being rewritten somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does It Work?
&lt;/h2&gt;

&lt;p&gt;Yes, and I checked both slots rather than assuming.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;claude-ds &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Reply with exactly: OK"&lt;/span&gt;
&lt;span class="go"&gt;⚠ claude.ai connectors are disabled because ANTHROPIC_API_KEY or another
  auth source is set and takes precedence over your claude.ai login
OK

&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;claude-ds &lt;span class="nt"&gt;--model&lt;/span&gt; opus &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Reply with exactly: OPUS-OK"&lt;/span&gt;
&lt;span class="go"&gt;OPUS-OK

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

&lt;/div&gt;



&lt;p&gt;That connectors warning is expected and it is scoped to the DeepSeek session only. It is Claude Code correctly telling you that an API key is in play. Since the key only exists inside that one child process, your normal &lt;code&gt;claude&lt;/code&gt; still has its login and its connectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Is For
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/eristoddle/april-2026-model-roundup-opus-47-official-deepseek-v4-open-sources-1m-context-and-gpt-55-47m1"&gt;DeepSeek V4&lt;/a&gt; is not Opus. Anyone selling you that is selling something. But it is cheap enough that I stop doing the mental arithmetic before every prompt, in an interface that I am already really used to.&lt;/p&gt;

&lt;p&gt;The reason I kept going back to Claude Code even when I had a cheaper option running in another tool was never capability. I simply know where everything is there. Now the cheap path and the familiar path are the same path. I am still using both Claude Code with Claude models and Opencode, but now I can switch to a really cheap option and start on non-critical work quickly. Today I used it to run a &lt;a href="https://dev.to/eristoddle/the-agent-skills-guide-i-wish-id-had-17i1"&gt;deep research skill&lt;/a&gt; on a topic I am learning and it worked like a charm.&lt;/p&gt;

&lt;p&gt;Anyway. My key still has most of its credits on it, which after two live test calls feels about right. Now I have to go find out what happens when I turn DeepSeek loose on a repo that does matter.&lt;/p&gt;

</description>
      <category>claudecodedeepseek</category>
      <category>llmcostoptimization</category>
      <category>deepseekapisetup</category>
      <category>anthropicbaseurlerro</category>
    </item>
    <item>
      <title>Grok 4.6 Hit the Frontier at Bargain-Bin Prices</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 18 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/grok-46-hit-the-frontier-at-bargain-bin-prices-365</link>
      <guid>https://dev.to/eristoddle/grok-46-hit-the-frontier-at-bargain-bin-prices-365</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjj6b8u92s37mdbw9hnry.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjj6b8u92s37mdbw9hnry.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For about a year now the deal has been simple. You want the frontier, you pay frontier prices. Twenty-five, fifty bucks a million tokens. Or you go cheap and you accept that you’re running something a tier down, good enough for most jobs but not the thing topping the leaderboards. Premium or bargain. Pick a lane.&lt;/p&gt;

&lt;p&gt;This week that deal broke from three directions inside about 48 hours. xAI shipped a model that sits at the actual intelligence frontier and charges bargain-bin prices for it. Google shipped a cheap coding workhorse while its actual flagship stayed exactly as imaginary as it was last month. And the open-weights promise I spent all of last week’s post complaining about? It shipped. The weights are real. You can download them this morning.&lt;/p&gt;

&lt;p&gt;And through all of it, the single cheapest model on my boards kept quietly beating things that cost 57 times more. Same model I’ve been recommending since April. Let me walk you through it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grok 4.6 Walked Up to the Frontier and Sat Down&lt;/li&gt;
&lt;li&gt;Google Shipped Another Flash While the Flagship Stays a Ghost&lt;/li&gt;
&lt;li&gt;The Broken Promise From Last Week Actually Shipped&lt;/li&gt;
&lt;li&gt;Newest Still Isn’t Best&lt;/li&gt;
&lt;li&gt;Cheapskate Picks: Where the Money Actually Is&lt;/li&gt;
&lt;li&gt;Horror Stories From the Wild&lt;/li&gt;
&lt;li&gt;Coming Soon (Or “Soon,” Anyway)&lt;/li&gt;
&lt;li&gt;What I Actually Took Away This Week&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Grok 4.6 Walked Up to the Frontier and Sat Down
&lt;/h2&gt;

&lt;p&gt;Grok 4.6 landed on August 12, about five weeks after 4.5, and it was live in Cursor, Grok Build, and the API the same afternoon. No slow rollout, no waitlist. Here it is, go use it.&lt;/p&gt;

&lt;p&gt;The number that matters: it jumped roughly 5 points on the Artificial Analysis Intelligence Index to land at 61. That ties GPT-5.6 Sol and sits two points behind Claude Opus 5. That is the frontier. Not “the frontier for the price,” not “punching above its weight.” The actual top cluster, the models everyone pays a premium to touch.&lt;/p&gt;

&lt;p&gt;Now the price. Grok 4.6 is $2 in, $6 out per million tokens. Flat, unchanged from 4.5. GPT-5.6 Sol, the model it just tied on intelligence, is $5 in and $30 out. Do that division. For the cost of running one GPT-5.6 Sol job you can run the frontier-tier Grok five times over. &lt;a href="https://artificialanalysis.ai/articles/grok-4-6-benchmarks-and-analysis" rel="noopener noreferrer"&gt;Artificial Analysis put it plainly&lt;/a&gt; in their own headline: Grok 4.6 returns xAI to the intelligence frontier and leads on cost efficiency. The context window is still 500k, unchanged, which is the one spec that didn’t move.&lt;/p&gt;

&lt;p&gt;Here’s the asterisk, because there’s always an asterisk. On AA-Omniscience, the benchmark that measures whether a model knows what it doesn’t know, Grok 4.6 scores 48.2% accuracy and a 65.7% non-hallucination rate. Translate that: when Grok hits something it genuinely doesn’t know, it declines to answer about two times out of three, and it confidently makes something up the other third. A brand-new model at the top of the intelligence index that fabricates on one in three unknowns is not a dealbreaker. But if you’re about to wire it into an agent loop where it can act on its own confident guesses, you want to know that number before, not after.&lt;/p&gt;

&lt;p&gt;Arena hasn’t caught up yet, which is normal. Grok 4.6 is only #44 on the Overall board on a few thousand fresh votes, because Arena is a popularity contest and popularity takes weeks to accumulate. So you get the classic split: the hard benchmarks love it, the blind-taste crowd hasn’t voted. It’s smarter than it looks in the booth. Give the votes a couple weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Google Shipped Another Flash While the Flagship Stays a Ghost
&lt;/h2&gt;

&lt;p&gt;On August 13, one day after Grok, Google put out Gemini 3.7 Flash. That’s 23 days after Gemini 3.6 Flash. Three weeks. Google is iterating the cheap tier faster than most labs update their changelog.&lt;/p&gt;

&lt;p&gt;And it’s a real update, not a version-number bump. On Google’s own DeepSWE v1.1 coding benchmark it scores 65.3% against 3.6 Flash’s 49.0%. That’s a 16-point jump on real software-engineering tasks. They didn’t retrain from scratch either, just algorithmic improvements and user feedback layered onto the previous version, then shipped as a full replacement. On the Artificial Analysis index it lands at 56, and it’s one of the fastest models AA tracks, around 344 output tokens a second. Introductory pricing is $0.75 in, $3.75 out through the end of the year. It’s live in AI Studio, Android Studio, Antigravity, and the enterprise platform. On Arena it’s already #3 in Creative Writing and #4 in Math, though both of those ride preliminary vote counts in the hundreds, so treat them as a strong first impression under flattering light.&lt;/p&gt;

&lt;p&gt;Here’s the part that makes me laugh, though. &lt;a href="https://www.axios.com/2026/08/13/google-gemini-37-flash" rel="noopener noreferrer"&gt;Axios noticed it too&lt;/a&gt;: Gemini 3.7 Flash arrived before Gemini 3.5 Pro. The Pro. The flagship. The one Sundar Pichai promised at I/O back on May 19 would land “within a month.”&lt;/p&gt;

&lt;p&gt;That was roughly ninety days ago. &lt;a href="https://www.forbes.com/sites/johnwerner/2026/08/13/gemini-35-pro-delay-continues/" rel="noopener noreferrer"&gt;Forbes ran a piece on August 13&lt;/a&gt; with the deeply original title “Gemini 3.5 Pro Delay Continues.” People have started calling it the longest-awaited model of 2026. The reporting says the team hit a structural problem, scrapped the base model, rebuilt it, and that Google has already started pretraining an entirely new flagship it’s calling Gemini 4. So the flagship is so broken they’re skipping ahead to its replacement while shipping Flash after Flash after Flash to keep the lights on.&lt;/p&gt;

&lt;p&gt;I’m not complaining, exactly. The Flash tier is where the value is and Google’s clearly good at it. But when a company ships three iterations of its budget model in the time its premium model goes from “next month” to “we started building the next one instead,” that tells you where the actual engineering is landing. It’s landing on cheap and fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Broken Promise From Last Week Actually Shipped
&lt;/h2&gt;

&lt;p&gt;If you read last week’s post, you watched me go looking for Qwen3.8-Max’s open weights with my coffee and come back with nothing. Alibaba had promised them “the week of August 10” and the deadline came and went with no license, no files, no new date. I filed it under broken promises and moved on.&lt;/p&gt;

&lt;p&gt;Well. On August 12 they shipped. &lt;a href="https://www.mindstudio.ai/blog/qwen3-8-2-4t-a95b-release" rel="noopener noreferrer"&gt;Qwen3.8-2.4T-A95B went up on Hugging Face and ModelScope&lt;/a&gt;, 2.4 trillion parameters with 95 billion active, alongside the smaller Qwen3.8-27B that actually fits on a workstation. First time Alibaba has ever put a Max-class model in the public’s hands. About two days late, which in this business is basically on time. So the “China promised and stalled” beat from last week only half held. They stalled, then they delivered.&lt;/p&gt;

&lt;p&gt;The independent grade came in at 58 on the intelligence index, which puts it just under the 60-to-63 frontier cluster. Good model, not a record-breaker, and now that the weights are public the real test starts: what do people build with it and how does it hold up under evals that Alibaba didn’t run itself.&lt;/p&gt;

&lt;p&gt;And it wasn’t the only open drop. On August 14, Z.ai quietly released GLM-5.3. It’s not on Arena yet so I can’t rank it, but Z.ai’s GLM line has anchored my cheapskate picks for months, so it goes straight on the watch list. When the boards catch up, we’ll see where it lands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Newest Still Isn’t Best
&lt;/h2&gt;

&lt;p&gt;Quick detour to the top of the boards, because it keeps being true and it keeps mattering. Anthropic owns the leader slot in five of six Arena categories again. But look at &lt;em&gt;which&lt;/em&gt; Anthropic model is winning.&lt;/p&gt;

&lt;p&gt;On the Overall board the leader is Claude Fable 5. On Instruction Following and Hard Prompts, the leader is Opus 4.6, the high-effort variant. Not Opus 5. The newest, most expensive, top-of-the-intelligence-index flagship sits at #7 and #10 on Overall, behind its own older siblings. Opus 5 only clearly wins the Math board, and it does that on 437 votes, which is thin enough to wobble.&lt;/p&gt;

&lt;p&gt;So even inside a single lab, “newest” and “what blind human raters actually prefer” are pointing at different models. The version number went up. The preference didn’t follow. Every time a lab tells you the new one is smarter, remember that smarter on a benchmark and better in your actual work are two different measurements, and the second one is the one you’re paying for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheapskate Picks: Where the Money Actually Is
&lt;/h2&gt;

&lt;p&gt;This is the section I write the whole thing for. Method first, because the table is meaningless without it. For each Arena category, take the leader’s rating, draw a line 50 points below it, and everything above that line is the competitive band. Statistically it’s a coin-flip away from the “best” model. Then sort that band by output price and grab the cheapest thing in it. The mistake I’ve made before is reading the band off the visible top 20. The band is defined by &lt;em&gt;points&lt;/em&gt;, not rank, and it runs way deeper than the first screen. The Overall band this week is 57 models deep. The cheap open-weight stuff lives down in the 30s and 50s, a rounding error behind the premium brands and an order of magnitude cheaper. So I pulled the full tables and computed the bands in code.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ leader&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ pick&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Price ratio&lt;/th&gt;
&lt;th&gt;AA Pareto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#38)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-38&lt;/td&gt;
&lt;td&gt;~57×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#25)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-34&lt;/td&gt;
&lt;td&gt;~57×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;Gemini 3.6 Flash (#12)&lt;/td&gt;
&lt;td&gt;$1.88&lt;/td&gt;
&lt;td&gt;-33&lt;/td&gt;
&lt;td&gt;~27×&lt;/td&gt;
&lt;td&gt;nearby&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;claude-opus-4-6&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#25)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-44&lt;/td&gt;
&lt;td&gt;~29×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;claude-opus-4-6&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#28)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-37&lt;/td&gt;
&lt;td&gt;~29×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;claude-opus-5-max&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;Gemini 3.6 Flash (#7)&lt;/td&gt;
&lt;td&gt;$1.88&lt;/td&gt;
&lt;td&gt;-41&lt;/td&gt;
&lt;td&gt;~13×&lt;/td&gt;
&lt;td&gt;nearby&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few things worth saying out loud.&lt;/p&gt;

&lt;p&gt;MiMo v2.5 Pro sweeps three of six again, all at $0.87 output. That’s Xiaomi’s model from April, the one I’ve recommended every week for over a month now. This is the fifth cycle running it’s been the cheapest thing inside the competitive band of multiple categories, and it’s still sitting on &lt;a href="https://artificialanalysis.ai/models/mimo-v2-5-pro" rel="noopener noreferrer"&gt;Artificial Analysis’s Intelligence-vs-Cost Pareto frontier&lt;/a&gt;, index score 43, in the most efficient quadrant. The popularity metric and the capability metric keep independently landing on the same cheap model. That’s the strongest buy signal this newsletter produces, and it simply will not change. On OpenRouter it routes across &lt;a href="https://openrouter.ai/xiaomi/mimo-v2.5-pro" rel="noopener noreferrer"&gt;seven providers with a 30% discount live right now&lt;/a&gt;, no geo-lock, purchasable everywhere. The trade is speed: it’s slow, around 56 tokens a second, so for a tight agent loop where latency compounds you might pay up. For everything else, it’s the boring correct answer.&lt;/p&gt;

&lt;p&gt;Its ranks look scary until you check the vote counts. That #38 Overall rating is backed by more than 50,000 votes. A #28 Hard Prompts slot sits on 33,000. Those are far more settled numbers than the preliminary top-10 entries riding a few hundred votes. Deep rank measures preference, not reliability. Don’t let it spook you.&lt;/p&gt;

&lt;p&gt;Creative Writing and Math flipped this week, and the reason is a price cut. Gemini 3.6 Flash, which I quoted at $3.75 last issue, now shows up on Arena at $0.38 in and $1.88 out. That’s a straight halving, almost certainly Google trimming the old tier the moment 3.7 Flash launched on top of it. At $1.88 it’s the cheapest thing in both the Creative band and the Math band, and it beats every Opus except Fable 5 in Creative. Math is the compressed board as always, only 10 models deep, and the whole thing rides thin preliminary votes, so treat that pick as directional rather than gospel.&lt;/p&gt;

&lt;p&gt;And there’s a wildcard I have to name because the method demands it. On the Overall board, hy3, which is Tencent’s Hunyuan 3, sits at #54 with a $0.53 output price. That’s cheaper than MiMo. But it’s parked right at the leader-minus-50 line with a rating margin wide enough to slip below the cutoff on any given day, on only 4,600 votes. So it’s the cheaper gamble, not the anchor. If you want to ride the very edge of the band to save another thirty cents a million, it’s sitting right there. I’m keeping MiMo as the pick because I like my recommendations boring and my vote counts high.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horror Stories From the Wild
&lt;/h2&gt;

&lt;p&gt;Three this week, running from “new model problem” to “your problem” to “everyone’s problem.”&lt;/p&gt;

&lt;p&gt;First, the one I already flagged: Grok 4.6’s fabrication rate. A frontier model that makes something up on one in three of the things it doesn’t know is fine for a chat window where you can eyeball the answer. It is not fine bolted into an autonomous loop where its confident guess becomes the next tool call. New model, top of the index, still lies to you a third of the time it’s cornered. Know that going in.&lt;/p&gt;

&lt;p&gt;Second, a story that’s becoming the defining nightmare of agentic coding. &lt;a href="https://www.truefoundry.com/blog/llm-cost-attribution-agentic-cicd" rel="noopener noreferrer"&gt;A frontend team deployed a new agent&lt;/a&gt; that hallucinated a missing dependency, then entered a 400-step resolution loop trying to fix a problem that never existed. Every one of those 400 steps re-sent the entire accumulated context. Every step billed. The model invented a problem and then spent your money in a circle trying to solve it.&lt;/p&gt;

&lt;p&gt;Third, the cost story, because it’s the one that gets everyone eventually. &lt;a href="https://leanopstech.com/blog/agentic-ai-cost-runaway-token-budget-2026/" rel="noopener noreferrer"&gt;One developer kicked off an autonomous refactoring run&lt;/a&gt; over a long weekend, on a workload the team hadn’t even validated, and came back to a $4,200 API bill. The broader pattern the piece describes: within about 90 days of switching on coding agents, the AI bill becomes the second-largest line item on the engineering ledger, right after salaries. This is exactly why the cheapskate math isn’t a hobby. When a single unattended session can drain four figures, the difference between $0.87 and $50 a million stops being an abstraction and starts being your quarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming Soon (Or “Soon,” Anyway)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemini 3.5 Pro.&lt;/strong&gt; Still vapor, now roughly ninety days past Google’s “within a month.” Reportedly scrapped and rebuilt over reliability and coding failures, with Google already pretraining Gemini 4 in the background. I’ll believe it when the API returns a token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qwen3.8 open weights.&lt;/strong&gt; These actually shipped on August 12. The story now isn’t the launch, it’s the independent evals. Watch what the community builds and benchmarks over the next couple weeks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GLM-5.3.&lt;/strong&gt; Z.ai dropped it August 14. Not on Arena yet. Given how often GLM models have anchored these picks, it’s the one I’m most curious to see ranked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grok 4.6 in the EU.&lt;/strong&gt; As usual, xAI’s European rollout is lagging the US launch. If you’re on that side of the Atlantic, expect it later in the month.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Actually Took Away This Week
&lt;/h2&gt;

&lt;p&gt;The wall between “frontier” and “cheap” is coming down, and it’s coming down fast.&lt;/p&gt;

&lt;p&gt;A year ago the frontier was a walled garden you paid $30 a million to enter. This week a frontier-tier model shipped at $6 output, a cheap coding model got 16 points better in three weeks, and a Max-class model’s weights went public for anyone to download. Meanwhile the flagship everyone waited all summer for is so broken its maker started over, and the $0.87 model from April kept winning categories nobody talks about.&lt;/p&gt;

&lt;p&gt;The launches change. The headlines change. The correct move does not. Open the leaderboards, find the cheapest model inside the competitive band, confirm two different metrics agree it’s actually good, and run that. This week that’s still MiMo v2.5 Pro at 57 times less than the thing at the top of the board. And if you’re feeling brave, Grok 4.6 is now a genuine frontier option at a price that doesn’t require a finance meeting.&lt;/p&gt;

&lt;p&gt;Next Tuesday, same coffee, same two tabs. Some lab will have promised me something by then. I’ll believe that one when I can download it too.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
    </item>
    <item>
      <title>How to Sync Obsidian on Android for Free</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Fri, 14 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/how-to-sync-obsidian-on-android-for-free-41m</link>
      <guid>https://dev.to/eristoddle/how-to-sync-obsidian-on-android-for-free-41m</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft2r0vsjqkygdrpx43xq7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft2r0vsjqkygdrpx43xq7.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I sync five devices. An iPad is in that pile, and the iPad is what makes it complicated. iOS hands you a sandbox and a shrug.&lt;/p&gt;

&lt;p&gt;Android is not that. It has a real filesystem, real background services, and apps that can touch each other’s folders. Almost everything that makes syncing Obsidian on an iPhone annoying just does not apply. If you came here from &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-across-all-your-devices-including-free-methods-1mi5"&gt;my guide to syncing Obsidian for free on every device&lt;/a&gt; for the Android specifics, this is the platform where the free options actually win.&lt;/p&gt;

&lt;p&gt;The catch is one decision you make before any of it. So let’s start there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where Your Vault Lives Decides Everything Else&lt;/li&gt;
&lt;li&gt;Why “Obsidian Can’t See My Folder” Happens&lt;/li&gt;
&lt;li&gt;Syncthing Is the Best Free Answer, and Every Guide Is Now Wrong About It&lt;/li&gt;
&lt;li&gt;FolderSync and Dropsync: The Cloud Folder Route&lt;/li&gt;
&lt;li&gt;Google Drive on Android Is Worse Than It Looks&lt;/li&gt;
&lt;li&gt;The Settings That Silently Kill Your Sync&lt;/li&gt;
&lt;li&gt;Windows Plus Android, Specifically&lt;/li&gt;
&lt;li&gt;
Frequently Asked Questions

&lt;ul&gt;
&lt;li&gt;Where is the Obsidian vault located on Android?&lt;/li&gt;
&lt;li&gt;Can you sync Obsidian on Android for free?&lt;/li&gt;
&lt;li&gt;Does Obsidian sync with Google Drive on Android?&lt;/li&gt;
&lt;li&gt;Can you sync Obsidian between Windows and Android?&lt;/li&gt;
&lt;li&gt;Does Obsidian work with Dropbox on Android?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Short Version&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where Your Vault Lives Decides Everything Else
&lt;/h2&gt;

&lt;p&gt;Open Obsidian on a fresh Android install and it asks where to put the vault. Two options: &lt;strong&gt;device storage&lt;/strong&gt; or &lt;strong&gt;app storage&lt;/strong&gt;. It looks like a privacy preference. It is the sync decision, made before you have thought about sync at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Device storage&lt;/strong&gt; puts the vault in the shared filesystem, somewhere like &lt;code&gt;/storage/emulated/0/Documents/Obsidian&lt;/code&gt;, which your file manager shows as plain &lt;code&gt;Documents/Obsidian&lt;/code&gt;. Other apps can see it. Obsidian asks for the “All files access” permission to do this, which feels invasive and is why a lot of people click the other button. &lt;a href="https://help.obsidian.md/mobile" rel="noopener noreferrer"&gt;Obsidian’s own docs&lt;/a&gt; recommend device storage anyway, for compatibility: any tool that syncs files, &lt;a href="https://syncthing.net/" rel="noopener noreferrer"&gt;Syncthing&lt;/a&gt;, &lt;a href="https://play.google.com/store/apps/details?id=dk.tacit.android.foldersync.lite&amp;amp;hl=en_US" rel="noopener noreferrer"&gt;FolderSync&lt;/a&gt;, &lt;a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync&amp;amp;hl=en_US" rel="noopener noreferrer"&gt;Dropsync&lt;/a&gt;, a git client, has to be able to see those files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App storage&lt;/strong&gt; puts the vault in Obsidian’s private sandbox. No scary permission prompt, better isolation, and genuinely the right answer for some people. It also means nothing outside Obsidian can read the vault. &lt;a href="https://obsidian.md/sync" rel="noopener noreferrer"&gt;Obsidian Sync&lt;/a&gt; works. Plugins that sync over the network, like &lt;a href="https://github.com/remotely-save/remotely-save" rel="noopener noreferrer"&gt;Remotely Save&lt;/a&gt;, work, because they run inside Obsidian. Syncthing does not. FolderSync does not. No external app does. It is the whole point of the sandbox.&lt;/p&gt;

&lt;p&gt;And the part worth putting in bold: &lt;strong&gt;if you use app storage and uninstall Obsidian, the local vault is deleted with it.&lt;/strong&gt; Android deletes app-private data on uninstall. Your other devices keep their copies if you were syncing, but the phone’s copy is gone.&lt;/p&gt;

&lt;p&gt;So the branch is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Want to use Syncthing, FolderSync, Dropsync, or a git client? &lt;strong&gt;Device storage.&lt;/strong&gt; Grant the permission.&lt;/li&gt;
&lt;li&gt;Only ever going to use Obsidian Sync or a sync plugin? &lt;strong&gt;App storage&lt;/strong&gt; is fine and slightly tidier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you picked wrong, you are not stuck, but Obsidian will not move a vault for you. Make a new vault in the other location, copy the notes across with a file manager or from your desktop copy, and open that one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why “Obsidian Can’t See My Folder” Happens
&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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsium1ax9hv1a1thlpecm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsium1ax9hv1a1thlpecm.jpg" alt="Why" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other half of this is scoped storage, Android’s permission model for file access, which Obsidian has been fighting for years. Obsidian’s docs are blunt about it: scoped storage runs a permission check on every single file operation, which tanks performance in an app touching hundreds of small markdown files, and it gives no way to watch for external changes.&lt;/p&gt;

&lt;p&gt;That second one is what bites sync users. Watching for external changes is exactly what you need when another app is writing to your vault in the background. It is why Obsidian wants the broad “All files” permission instead of the narrow folder picker, and why a vault Obsidian only has partial access to behaves like it is haunted.&lt;/p&gt;

&lt;p&gt;Practical version: put the vault somewhere boring in shared storage. Not inside another app’s private directory, and not on an SD card if you can avoid it. Then point your sync tool at that same path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syncthing Is the Best Free Answer, and Every Guide Is Now Wrong About It
&lt;/h2&gt;

&lt;p&gt;Syncthing is peer to peer. Your devices talk directly, there is no cloud account, no storage cap, no monthly anything, and on Android it runs as a real background service instead of begging the OS for scraps. For a vault of text files it is close to ideal, and it is what I would use if I did not have an iPad in the mix. (For the iPad half of that problem, see &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-on-iphone-and-ipad-for-free-in-2026-427p"&gt;syncing Obsidian on iPhone and iPad for free&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Here is the thing every existing Android guide gets wrong, including a fair number published this year: &lt;strong&gt;the &lt;a href="https://github.com/syncthing/syncthing-android" rel="noopener noreferrer"&gt;official Syncthing Android app&lt;/a&gt; was discontinued.&lt;/strong&gt; Its final release shipped with the December 2024 version of Syncthing. The maintainers &lt;a href="https://forum.syncthing.net/t/discontinuing-syncthing-android/23002" rel="noopener noreferrer"&gt;cited Google Play publishing friction and a lack of active development&lt;/a&gt;. If a tutorial tells you to grab “Syncthing” from the Play Store, that tutorial is pointing you at an abandoned app.&lt;/p&gt;

&lt;p&gt;The successor is &lt;strong&gt;&lt;a href="https://github.com/researchxxl/syncthing-android" rel="noopener noreferrer"&gt;Syncthing-Fork&lt;/a&gt;&lt;/strong&gt;, which has been the better Android build for years anyway. Its maintainer, Catfriend1, then retired and handed the project to researchxxl, in a way that briefly made the repo vanish from GitHub and made everyone reasonably nervous. That got sorted out in public: F-Droid and Syncthing developers reviewed the new repo, found no sign of anything malicious, confirmed the old commits were unaltered, and the builds are reproducible, which is the actual defense against a supply chain attack.&lt;/p&gt;

&lt;p&gt;I am telling you that instead of just handing you a link because it is your notes. Install it from &lt;strong&gt;&lt;a href="https://f-droid.org/packages/com.github.catfriend1.syncthingfork/" rel="noopener noreferrer"&gt;F-Droid&lt;/a&gt;&lt;/strong&gt;, which builds from source and has a slower review window between updates. That is exactly the property you want on a project that just changed hands.&lt;/p&gt;

&lt;p&gt;Setup, once you have it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F24ale56cur3sdh6cvp7k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F24ale56cur3sdh6cvp7k.jpg" alt="Syncthing Is the Best Free Answer, and Every Guide Is Now Wrong About It" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Syncthing-Fork on the phone from F-Droid, and &lt;a href="https://syncthing.net/downloads/" rel="noopener noreferrer"&gt;Syncthing&lt;/a&gt; on your desktop.&lt;/li&gt;
&lt;li&gt;Open the desktop UI, which is the part that throws everyone. Syncthing has no window and no icon. It runs as a background service and you configure it in a browser at &lt;code&gt;http://localhost:8384&lt;/code&gt;. That page is the whole app.&lt;/li&gt;
&lt;li&gt;On that page, click Add Folder, point it at your vault, and note the Folder ID it generates.&lt;/li&gt;
&lt;li&gt;Pair the devices. On the desktop, Actions, then Show ID, which gives you a long string and a QR code. On the phone, Devices tab, the plus button, then scan that code. The desktop throws a prompt asking whether it should talk to this new device. Accept it.&lt;/li&gt;
&lt;li&gt;Back on the desktop, edit the vault folder, open its Sharing tab, and tick the phone. Now the phone gets a notification asking where to put the folder. That is where you point it at your device-storage vault location.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;.obsidian/workspace.json&lt;/code&gt; and &lt;code&gt;.obsidian/workspace-mobile.json&lt;/code&gt; to the ignore patterns &lt;strong&gt;on both devices.&lt;/strong&gt; Ignore patterns in Syncthing are per device, not per folder, so setting them on the desktop does exactly nothing for the phone. Both live in the same place: edit the folder, Ignore Patterns tab. These two files are per-device UI state and they change constantly, which means they conflict constantly. Nothing else in &lt;code&gt;.obsidian&lt;/code&gt; needs excluding, and you want your plugins and settings to sync.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then let it settle before you decide it’s broken. Give it ten minutes before you touch anything. A text vault is small, but the first pass still has to hash every file, and both ends show a percentage while it works. Watch that number move instead of assuming the thing is dead.&lt;/p&gt;

&lt;h2&gt;
  
  
  FolderSync and Dropsync: The Cloud Folder Route
&lt;/h2&gt;

&lt;p&gt;If your notes already live in &lt;a href="https://www.dropbox.com/" rel="noopener noreferrer"&gt;Dropbox&lt;/a&gt; or &lt;a href="https://www.microsoft.com/en-us/microsoft-365/onedrive/online-cloud-storage" rel="noopener noreferrer"&gt;OneDrive&lt;/a&gt; on the desktop and you want the phone to mirror that, this is the path. Both apps do the same job: watch a local folder, watch a remote cloud folder, keep them the same on a schedule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dropsync&lt;/strong&gt; is the Dropbox specialist, now published by &lt;a href="https://www.metactrl.com/" rel="noopener noreferrer"&gt;MetaCtrl&lt;/a&gt;, and it is actively maintained. It picked up updates through spring of this year, which is more than you can say for a lot of Android utilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FolderSync&lt;/strong&gt; is the generalist and talks to a long list of providers. Its pricing is genuinely confusing, so: there are two separate apps on Google Play. FolderSync (free, ad supported, with a Premium in-app purchase) and &lt;a href="https://play.google.com/store/apps/details?id=dk.tacit.android.foldersync.full&amp;amp;hl=en_US" rel="noopener noreferrer"&gt;FolderSync Pro&lt;/a&gt; (paid up front, a few dollars). Buying Premium in the free app gets feature parity with Pro but does not let you download Pro, because Play treats them as different apps. The license follows your Google account. Pick one and stay there.&lt;/p&gt;

&lt;p&gt;Setup is the same shape either way: create an account connection, create a folderpair, set local folder to your vault and remote folder to the vault in the cloud, sync type two-way, then a schedule.&lt;/p&gt;

&lt;p&gt;And now the caveat that makes this second choice rather than first. &lt;strong&gt;This is scheduled sync, not live sync.&lt;/strong&gt; Even at the most aggressive interval there is a window where phone and desktop disagree. Edit a note on the phone, walk to the laptop before the sync fires, edit it again there, and you have made a conflict by hand. Syncthing pushes on change and mostly dodges this. Cloud-folder sync does not.&lt;/p&gt;

&lt;p&gt;Also, and I will keep saying this until it stops eating people’s notes: &lt;strong&gt;run exactly one sync system.&lt;/strong&gt; Not Dropsync plus Syncthing “for redundancy.” Two schedulers writing the same files without knowing about each other is a race, and your note is the prize.&lt;/p&gt;

&lt;h2&gt;
  
  
  Google Drive on Android Is Worse Than It Looks
&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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdomh7fq4pobtnx58n0ff.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdomh7fq4pobtnx58n0ff.jpg" alt="Google Drive on Android Is Worse Than It Looks" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one gets its own section purely because of how reasonable it sounds. You have an Android phone, &lt;a href="https://www.google.com/drive/" rel="noopener noreferrer"&gt;Google Drive&lt;/a&gt; is right there, free and already signed in. Obviously that is the answer.&lt;/p&gt;

&lt;p&gt;It is not, because Google Drive has no two-way folder sync on Android. &lt;a href="https://www.google.com/drive/download/" rel="noopener noreferrer"&gt;Drive for desktop&lt;/a&gt; does that job on a computer and has no Android equivalent. The Drive app streams files on demand. It does not keep a plain folder on disk that Obsidian can open as a vault. Getting there means going around it: FolderSync connects to Drive as a provider, or you use the &lt;a href="https://github.com/stravo1/obsidian-gdrive-sync" rel="noopener noreferrer"&gt;Google Drive Sync plugin&lt;/a&gt;, which is still beta, is not in the community plugin directory, installs manually or through &lt;a href="https://github.com/TfTHacker/obsidian42-brat" rel="noopener noreferrer"&gt;BRAT&lt;/a&gt;, and whose own README carries a data loss warning I quote rather than paraphrase in the &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-across-all-your-devices-including-free-methods-1mi5"&gt;main sync guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are on Android and you want a cloud-storage-shaped answer, Dropbox with Dropsync is the one that works. Drive is the one that looks like it should work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Settings That Silently Kill Your Sync
&lt;/h2&gt;

&lt;p&gt;You will set all this up, confirm it works, pocket the phone, and find it three hours stale. That is not the sync tool. That is Android’s battery optimizer deciding your background service is a freeloader, and manufacturer skins are far more aggressive about it than stock Android.&lt;/p&gt;

&lt;p&gt;For whichever sync app you chose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Battery optimization: turn it off for that app.&lt;/strong&gt; Roughly Settings, Apps, the app, Battery, then Unrestricted, though the wording moves around by Android version and manufacturer. This is the one that matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disable background restrictions&lt;/strong&gt; , a separate toggle that is easy to miss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allow background data&lt;/strong&gt; , including on metered connections if you want sync off wifi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lock the app in the recents view&lt;/strong&gt; if your phone has that. Open recents, long press the app’s card or its icon, and pick the lock or pin option. Samsung, Xiaomi, and OnePlus kill “unused” background apps on their own schedule regardless of the standard settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syncthing-Fork specifically:&lt;/strong&gt; check its run conditions. It can be set to run only on wifi, only while charging, or only on certain networks, and the battery-friendly defaults are not always what you want.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If sync works while the screen is on and stops when it isn’t, you have found your problem. It is always this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Windows Plus Android, Specifically
&lt;/h2&gt;

&lt;p&gt;This combination comes up constantly and gets bad advice, usually some variant of “just use iCloud, there’s a Windows app.” Do not. Obsidian’s own documentation warns that iCloud Drive on Windows can lead to file duplication or corruption, which I dug into in &lt;a href="https://dev.to/eristoddle/obsidian-icloud-sync-in-2026-including-the-windows-problem-4503"&gt;the iCloud sync post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For Windows plus Android with no Apple device in the mix, ranked:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbjea16txv9lpgrh56lvj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbjea16txv9lpgrh56lvj.jpg" alt="Windows Plus Android, Specifically" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Syncthing.&lt;/strong&gt; Both platforms are first class, it is free with no storage cap, and there is no Apple sandbox to design around. This combo is where Syncthing is at its least annoying. On Windows, get it through &lt;a href="https://github.com/GermanCoding/SyncTrayzor" rel="noopener noreferrer"&gt;SyncTrayzor&lt;/a&gt;, which wraps Syncthing in an actual tray app instead of leaving you with a background service and a browser tab. And note the pattern repeating: the original SyncTrayzor is no longer maintained either, and the v2 fork is the one Syncthing’s own docs point at.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dropbox plus Dropsync.&lt;/strong&gt; If the notes are already in Dropbox, this is less work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remotely Save&lt;/strong&gt; , pointed at storage you already have: S3, Backblaze B2, any WebDAV server, Dropbox, or OneDrive. Runs inside Obsidian, so it works with app storage too, which none of the others do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Vinzent03/obsidian-git" rel="noopener noreferrer"&gt;Git&lt;/a&gt;&lt;/strong&gt;, if you already live in git. It is a real option on Android and a worse one than you expect on mobile generally, which I went through in &lt;a href="https://dev.to/eristoddle/obsidian-git-sync-in-2026-what-actually-works-on-mobile-46ad"&gt;what actually works for Obsidian git sync on mobile&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Where is the Obsidian vault located on Android?
&lt;/h3&gt;

&lt;p&gt;Wherever you put it, and that is the point. Device storage puts it in shared storage where other apps can reach it, typically under a &lt;code&gt;Documents&lt;/code&gt; folder. App storage puts it in Obsidian’s private directory, invisible to other apps and deleted if you uninstall Obsidian. Check which one you picked before troubleshooting a sync tool that cannot find your files. Open the vault switcher in Obsidian and look at the path under the vault name. If it starts with &lt;code&gt;/storage/emulated/0/&lt;/code&gt;, you are in device storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can you sync Obsidian on Android for free?
&lt;/h3&gt;

&lt;p&gt;Yes, more easily than on iOS. Syncthing is free with no storage limit, Remotely Save is free and connects to storage you already have, and Dropsync and FolderSync have free tiers that cover a vault of text notes. You never need an Obsidian Sync subscription on Android.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Obsidian sync with Google Drive on Android?
&lt;/h3&gt;

&lt;p&gt;Not directly. The Drive app streams files rather than keeping a real synced folder on disk, so there is nothing for Obsidian to open. You get there through FolderSync using Drive as a provider, or the third-party Google Drive Sync plugin, which is still beta and ships with a data loss warning. Dropbox is the smoother cloud option on Android.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can you sync Obsidian between Windows and Android?
&lt;/h3&gt;

&lt;p&gt;Yes, and it is one of the easier combinations because neither platform has an iOS-style sandbox. Syncthing is the best free answer. Dropbox with Dropsync works if your vault already lives in Dropbox. Avoid iCloud on Windows for this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Obsidian work with Dropbox on Android?
&lt;/h3&gt;

&lt;p&gt;Yes, through Dropsync or FolderSync rather than the Dropbox app itself, which does not keep a persistent local folder Obsidian can use as a vault. You need a sync utility to mirror the cloud folder to local storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Short Version
&lt;/h2&gt;

&lt;p&gt;Pick device storage. Grant the “All files” permission even though it feels wrong. Install Syncthing-Fork from F-Droid, not the dead official app. Ignore the two workspace files. Turn off battery optimization for whatever you installed. Run one sync system and only one.&lt;/p&gt;

&lt;p&gt;That is a genuinely free, genuinely reliable setup, and the only reason my own phone is not running it is that I own an iPad, which is a sentence that explains most of my sync decisions.&lt;/p&gt;

</description>
      <category>obsidian</category>
      <category>android</category>
      <category>sync</category>
      <category>syncthing</category>
    </item>
    <item>
      <title>The Open-Weights Promise Qwen Broke (and Meta Kept)</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 11 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/the-open-weights-promise-qwen-broke-and-meta-kept-44m4</link>
      <guid>https://dev.to/eristoddle/the-open-weights-promise-qwen-broke-and-meta-kept-44m4</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8wk0r9kup8tk45f5dtlw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8wk0r9kup8tk45f5dtlw.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week Alibaba dropped Qwen3.8-Max and promised the open weights were landing “next week.” Well. It’s next week. I went looking for them this morning with my coffee, and there’s nothing on Hugging Face, no license, and no new date. The 2.4-trillion-parameter monster everyone lost their minds over is still API-only, still a black box, still grading its own homework.&lt;/p&gt;

&lt;p&gt;Meanwhile, the other side of the world did the exact opposite. Meta shipped a coding model and a terminal agent, then turned around and said it’s going to &lt;em&gt;open&lt;/em&gt; the weights. So this week the script flipped. China promised open and didn’t deliver. The US shipped and pledged to open up. And me? I’m still running the same $0.87 model from April that I was running last week, and the week before that, and the week before that.&lt;/p&gt;

&lt;p&gt;Let me walk you through it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Open-Weights Promise That Evaporated&lt;/li&gt;
&lt;li&gt;Meanwhile, Meta Did the Opposite&lt;/li&gt;
&lt;li&gt;The Catch in Meta’s Cheap Tier&lt;/li&gt;
&lt;li&gt;The Boring Answer, Week Four&lt;/li&gt;
&lt;li&gt;Cheapskate Picks: Where the Money Actually Is&lt;/li&gt;
&lt;li&gt;Horror Stories From the Wild&lt;/li&gt;
&lt;li&gt;Coming Soon (Or “Soon,” Anyway)&lt;/li&gt;
&lt;li&gt;What I Actually Took Away This Week&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Open-Weights Promise That Evaporated
&lt;/h2&gt;

&lt;p&gt;Here’s where we left Qwen3.8-Max last Tuesday. Genuinely impressive spec sheet. 2.4 trillion parameters, 95 billion active, a million-token context window, priced at roughly a quarter of Claude Opus 5. It rocketed onto the Arena boards on day one. And Alibaba said the weights, plus a smaller Qwen3.8-27B, would go public &lt;a href="https://www.datacamp.com/blog/qwen3-8-max" rel="noopener noreferrer"&gt;the week of August 10 on Hugging Face and ModelScope&lt;/a&gt;. First open-weight release at Max scale for the Qwen line. Big deal.&lt;/p&gt;

&lt;p&gt;That week is now. &lt;a href="https://byteiota.com/qwen3-8-open-weights-drop-this-week-read-before-you-download/" rel="noopener noreferrer"&gt;The weights haven’t appeared, no license has been named, and Alibaba hasn’t given a new date&lt;/a&gt;. The 27B is vapor too. No architecture details, no context length, no license, nothing.&lt;/p&gt;

&lt;p&gt;The good news for the model, if you’re keeping score, is that it finally got an independent grade. Last week the only benchmarks were Alibaba’s own, in a table that helpfully scored its competitors for them. This week Artificial Analysis actually ran it and &lt;a href="https://benchlm.ai/benchmarks/artificialanalysis" rel="noopener noreferrer"&gt;landed it at 56 on the Intelligence Index&lt;/a&gt;. Which is fine. It’s a good model. But 56 sits below the top cluster of Opus 5 at 61, Fable 5 at 60, GPT-5.6 Sol at 59, and Kimi K3 at 57. So the one hard number we got came in under the launch-day hype, and the open weights that were supposed to let anyone verify the rest didn’t show. If you rewired your stack around that press release, this is your reminder not to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meanwhile, Meta Did the Opposite
&lt;/h2&gt;

&lt;p&gt;While Alibaba was quietly not shipping, Meta was loudly shipping. On August 5 it put out &lt;a href="https://www.developersdigest.tech/blog/meta-muse-code-spark-1-2-release" rel="noopener noreferrer"&gt;Muse Spark 1.2 and a terminal coding agent called Muse Code&lt;/a&gt;. The model is a coding specialist with a million-token context, built for the whole plan-execute-validate-fix loop across a big codebase instead of spitting out isolated snippets. It debuted at #4 on Arena Overall and #8 on the Coding board, though both of those ratings are riding preliminary vote counts in the low thousands, so treat them as a first impression with good lighting.&lt;/p&gt;

&lt;p&gt;Then, on August 10, Meta announced it’s going to open Muse Spark 1.2’s weights. It already opened a smaller sibling, Muse Glimmer, which is now &lt;a href="https://cryptobriefing.com/meta-muse-glimmer-spark-release/" rel="noopener noreferrer"&gt;showing up on the trackers&lt;/a&gt;. If the Spark 1.2 release actually lands, it’d be the strongest US open-weight model going right now.&lt;/p&gt;

&lt;p&gt;Sit with the reversal for a second, because it’s the real story this week. For a solid year the pattern was: American labs ship closed, Chinese labs give the good stuff away for pennies. This week Alibaba dangled open weights and pulled them back, and Meta is the one queuing up a genuine open release. One missed week isn’t a cancellation, and a pledge isn’t a release, so don’t over-read it. But the roles inverted, and that’s worth noticing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Catch in Meta’s Cheap Tier
&lt;/h2&gt;

&lt;p&gt;Now for the part where the cheapskate in me perks up and then immediately gets suspicious. Muse Code has a “contributor” tier. Standard pricing on Muse Spark 1.2 is $1.25 in and $4.25 out per million tokens. The contributor tier is &lt;a href="https://codersera.com/blog/muse-code-contributor-tier-privacy-2026/" rel="noopener noreferrer"&gt;$0.10 in and $0.20 out&lt;/a&gt;. That’s roughly 12 times cheaper on input and 21 times cheaper on output. My kind of number.&lt;/p&gt;

&lt;p&gt;Except you don’t pay in dollars. You pay in data. Everything you send and everything the model sends back becomes training material for future Meta models. And here’s the part that actually bugs me: Meta hasn’t said whether that data use stops at training, or whether it also covers evaluation, red-teaming, and product analytics. The scope is undefined, which in practice means you assume the worst.&lt;/p&gt;

&lt;p&gt;So the honest guidance is the boring guidance. Fine for public code, synthetic code, throwaway experiments, anything you’d have posted to a gist anyway. Absolutely not for client repos, secrets, NDA material, or unreleased product logic. This is the oldest cheapskate trap there is. The sticker price isn’t the real price. Sometimes the discount is the product and you’re the inventory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Boring Answer, Week Four
&lt;/h2&gt;

&lt;p&gt;Okay. Strip away the launch confetti and the broken promises. What’s the model that gives me the most quality per dollar right now?&lt;/p&gt;

&lt;p&gt;Same answer as last week. And the week before. MiMo v2.5 Pro. Xiaomi’s model from April, $0.43/$0.87 on Arena’s list price, &lt;a href="https://openrouter.ai/xiaomi/mimo-v2.5-pro" rel="noopener noreferrer"&gt;routing across seven providers on OpenRouter&lt;/a&gt; with no geo-lock. Listed, purchasable, cheap as dirt. This is now the fourth cycle running where it’s the cheapest thing inside the competitive band of four separate Arena categories, and it’s still sitting on &lt;a href="https://artificialanalysis.ai/" rel="noopener noreferrer"&gt;Artificial Analysis’s Intelligence-vs-Cost Pareto frontier&lt;/a&gt;. The popularity metric and the capability metric keep independently pointing at the same cheap model. That’s the strongest buy signal this newsletter ever produces, and it just refuses to change.&lt;/p&gt;

&lt;p&gt;While I’m here, one thing worth calling out about the top of the boards. Anthropic owns the leader spot in five of six Arena categories this week. But look at &lt;em&gt;which&lt;/em&gt; Anthropic model. On Instruction Following and Hard Prompts the leader is Opus 4.6-thinking. Not Opus 5. The newest, “smartest” flagship, the one that tops the hard-benchmark index, only clearly wins the Math board, and it does that on preliminary votes. So even inside one lab, “newest” and “what blind human raters actually prefer” are pointing in different directions. The word “smartest” is doing a lot of unearned work in the marketing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheapskate Picks: Where the Money Actually Is
&lt;/h2&gt;

&lt;p&gt;This is the section I write the whole thing for. The method, one more time, because it’s the only way the table makes sense. For each Arena category, take the leader’s rating, draw a line 50 points below it, and everything above that line is the competitive band. Statistically it’s a rounding error away from the “best” model. Sort that band by output price, take the cheapest thing in it. The trick I’ve screwed up before is that the band is defined by &lt;em&gt;points&lt;/em&gt;, not by rank. It runs way deeper than the visible top 20. The Overall band this week is about 53 models deep. The cheap open-weight models live down in the 30s and 40s, a couple of points behind premium brands and an order of magnitude cheaper. Truncate at rank 20 and you delete the entire reason this section exists.&lt;/p&gt;

&lt;p&gt;So I pulled the full tables and computed the bands in code. Here’s where the money is.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ leader&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ pick&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Price ratio&lt;/th&gt;
&lt;th&gt;AA Pareto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#37)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-38&lt;/td&gt;
&lt;td&gt;~57×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#27)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-35&lt;/td&gt;
&lt;td&gt;~57×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-fable-5&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;Gemini 3 Flash (#21)&lt;/td&gt;
&lt;td&gt;$3&lt;/td&gt;
&lt;td&gt;-48&lt;/td&gt;
&lt;td&gt;~17×&lt;/td&gt;
&lt;td&gt;nearby&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-thinking&lt;/td&gt;
&lt;td&gt;$12.50&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#24)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-44&lt;/td&gt;
&lt;td&gt;~14×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;claude-opus-4-6-thinking&lt;/td&gt;
&lt;td&gt;$12.50&lt;/td&gt;
&lt;td&gt;MiMo v2.5 Pro (#27)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;-38&lt;/td&gt;
&lt;td&gt;~14×&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;claude-opus-5-max&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;Gemini 3.6 Flash (#5)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;-39&lt;/td&gt;
&lt;td&gt;~6.7×&lt;/td&gt;
&lt;td&gt;nearby&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few things worth saying out loud.&lt;/p&gt;

&lt;p&gt;MiMo sweeps four of six again, all at $0.87 output. Its ranks look scary until you check the vote counts. That #37 Overall rating is backed by 50,000 votes. That’s a far more settled number than most of the preliminary top-10 entries sitting on a few hundred votes each. Deep rank measures preference, not reliability. Don’t let it spook you.&lt;/p&gt;

&lt;p&gt;Creative Writing is the one place MiMo can’t reach, same as always, because that board rewards polish and the cheap crowd falls just below the cutoff. The pick there is Gemini 3 Flash at $3 output, clinging to the edge of the band 48 points back, still 17 times cheaper than the leader. Math is the compressed board this week, only about 6 models deep, and the cheapest thing in it is Gemini 3.6 Flash at $3.75. Real discount, just a smaller one, and the leader up top is preliminary anyway.&lt;/p&gt;

&lt;p&gt;And there’s a wildcard I have to mention because the method demands it. On the Overall board, a model called hy3, which is Tencent’s Hunyuan 3, sits at rank #52 with an output price of $0.53. That’s cheaper than MiMo. But it’s parked at exactly the leader-minus-50 line, with a rating margin wide enough to dip below the cutoff on any given day. So it’s the cheaper gamble, not the anchor. If you want to ride the very edge of the band to save another thirty cents, it’s there. I’m keeping MiMo as the pick because I like my recommendations boring and my votes plentiful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horror Stories From the Wild
&lt;/h2&gt;

&lt;p&gt;Three this week, sliding from “your problem” to “everyone’s problem.”&lt;/p&gt;

&lt;p&gt;The first one I already told you: Meta’s contributor tier, where the cheapest coding option on the board is cheap precisely because it’s eating your prompts. If you saw the $0.20 output price and got excited before reading the fine print, that’s the fire. Go check what you piped through it.&lt;/p&gt;

&lt;p&gt;The second is Qwen3.8-Max’s disappearing act. Not a crash, just a broken promise with a benchmark table full of self-graded numbers behind it. The lesson is the same one this newsletter keeps preaching. Wait for someone who doesn’t work at the lab to run the model before you build anything on top of it.&lt;/p&gt;

&lt;p&gt;The third is the one that should actually scare you, because it’s not about any single model. It’s slopsquatting. Roughly &lt;a href="https://www.pearlorganisation.com/post/ai-hallucinations-in-enterprise-apps-real-costs-root-causes-and-how-to-fix-them" rel="noopener noreferrer"&gt;one in five package dependencies that AI coding assistants suggest simply don’t exist&lt;/a&gt;. Attackers know this. They watch for the common hallucinated package names and register real malware under those exact names. So your agent confidently invents an import, you run the install without blinking, and now you’ve pulled a payload onto your machine. The fix is unglamorous and non-negotiable: read your dependencies before you install them. Every time. Yes, even the ones that look obviously real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coming Soon (Or “Soon,” Anyway)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemini 3.5 Pro.&lt;/strong&gt; Still vapor. It was widely expected on August 7, then &lt;a href="https://nokiapoweruser.com/gemini-3-5-pro-delayed-again-deployment-issues/" rel="noopener noreferrer"&gt;got pushed again on “deployment issues”&lt;/a&gt;. That’s roughly &lt;a href="https://tech-insider.org/au/gemini-3-5-pro-67-days-delay-2026/" rel="noopener noreferrer"&gt;67 days past Google’s “within a month” promise from I/O&lt;/a&gt;, after the team reportedly scrapped and rebuilt the base model over coding and reliability failures. Google keeps shipping Flash tiers instead. I’ll believe it when I can call the API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qwen3.8-Max open weights.&lt;/strong&gt; Overdue as of this writing, no license, no date. If they land, the independent evals will be the story, not the launch table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meta Muse Spark 1.2 open weights.&lt;/strong&gt; Announced August 10. A pledge, not a release, but if it ships it’s the best US open-weight model out there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ling 3.0 Flash.&lt;/strong&gt; This one actually happened. Ant Group’s inclusionAI &lt;a href="https://www.businesswire.com/news/home/20260726584441/en/" rel="noopener noreferrer"&gt;open-sourced it August 5 under MIT&lt;/a&gt;, 124 billion parameters with 5.1 billion active, a 262K context. In a week defined by open weights that didn’t ship, a small Chinese lab quietly shipped some. Worth a look if you’re running your own hardware.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Actually Took Away This Week
&lt;/h2&gt;

&lt;p&gt;The frontier is boring and the promises are noise.&lt;/p&gt;

&lt;p&gt;Anthropic still owns the top of nearly every board and has for over a month. The interesting action is all down in the bargain bin, where a Chinese lab dangled open weights and yanked them, an American lab pledged to open its own, and a $0.87 model from April kept quietly winning four categories while nobody talked about it. The launches change. The headlines change. The correct move does not.&lt;/p&gt;

&lt;p&gt;Same advice as last week, and probably next week. Ignore the launch you read about in the news. Open the leaderboards, find the cheapest model inside the band, confirm two different metrics agree it’s actually good, and run that. This week that’s still MiMo v2.5 Pro at 57 times less than the thing everyone’s cheering for.&lt;/p&gt;

&lt;p&gt;And read your dependencies before you install them. I mean it. The slop is coming from inside the house now.&lt;/p&gt;

&lt;p&gt;Next Tuesday, same coffee, same two tabs. I fully expect another lab to have promised me something by then. I’ll believe that one when I can download it too.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
    </item>
    <item>
      <title>Somebody Finally Wrote Down Why My Coding Agents Keep Failing the Same Way</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Mon, 10 Aug 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/somebody-finally-wrote-down-why-my-coding-agents-keep-failing-the-same-way-13o</link>
      <guid>https://dev.to/eristoddle/somebody-finally-wrote-down-why-my-coding-agents-keep-failing-the-same-way-13o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fe9995dmeidzmy55h9d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fe9995dmeidzmy55h9d.jpg" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I read &lt;a href="https://www.amazon.com/Beyond-Code-AI-Assisted-Engineering-Mechanical-ebook/dp/B0H83HR8SH" rel="noopener noreferrer"&gt;&lt;em&gt;Beyond Code&lt;/em&gt;&lt;/a&gt; as a PDF in Apple Books, which means the only reason I have any notes on it is that I got annoyed enough last month to &lt;a href="https://dev.to/eristoddle/apple-books-hides-your-pdf-highlights-my-obsidian-plugin-now-digs-them-out-lio"&gt;make my own plugin dig the highlights out of Apple’s database&lt;/a&gt;. So the first thing this book did was justify a weekend I’d already spent.&lt;/p&gt;

&lt;p&gt;The second thing it did was produce 113 highlights in the first hundred pages. With this book I was highlighting entire paragraphs because I kept hitting sentences that described something I had personally screwed up and then written a blog post about.&lt;/p&gt;

&lt;p&gt;That’s the review, really. But I’ll take the long way there. Fair warning, I’m sixty percent in. Parts I through IV.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0d342iswzlpups1ngpjc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0d342iswzlpups1ngpjc.jpg" alt="Beyond Code by Jeremy McEntire" width="800" height="987"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What This Book Isn’t&lt;/li&gt;
&lt;li&gt;The Framing That Should Be on a Poster&lt;/li&gt;
&lt;li&gt;The Chapter That Made Me Go Look at My Own Repo&lt;/li&gt;
&lt;li&gt;What Not to Feed&lt;/li&gt;
&lt;li&gt;Mechanical Gates Over Advisory Review&lt;/li&gt;
&lt;li&gt;The Multi-Agent Thing&lt;/li&gt;
&lt;li&gt;Every Metric in My Pipeline Is Now Suspect&lt;/li&gt;
&lt;li&gt;Where It Loses Me a Little&lt;/li&gt;
&lt;li&gt;Where I Actually Am With It&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What This Book Isn’t
&lt;/h2&gt;

&lt;p&gt;The most important thing about this book is a thing that isn’t in it.&lt;/p&gt;

&lt;p&gt;There is no tool in this book. Not one. No “here’s my Claude Code setup.” No &lt;code&gt;.cursorrules&lt;/code&gt; walkthrough. No comparison table of Copilot versus Opencode versus whatever shipped last Tuesday and will be deprecated by the time you finish the chapter. No recommended library, no framework, no repo to clone. The author does not tell you which model to use. He does not tell you which agent harness to use. He never once tells you what to install.&lt;/p&gt;

&lt;p&gt;I’ve read a lot of books and many blog posts about AI-assisted development at this point, mine included, and nearly all of them sit at one of two extremes. Either they’re deeply technical and showing you how to write the code, or they’re written for stakeholders and exist to convince a CEO that AI deserves a budget line. Both have a shelf life of about six months, because the thing they’re really teaching you is a menu, and the menu changes. This book sits between the two, which happens to be the only place where you come away with a framework in your head instead of a list of settings.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Beyond Code&lt;/em&gt; is teaching you the physics. Every failure mode it describes is derived from a property of how attention works, or how information behaves when you compress it, or how optimization pressure behaves when you point it at a proxy. None of those change when a new model ships. McEntire says this outright, and it’s the line that made me trust the rest of the book:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The engineer who understands information loss at coordination boundaries, proxy optimization in evaluation systems, and the structural impossibility of quality-through-review-gates does not need to memorize a list of anti-patterns. They can derive the anti-patterns from the physics, and they can design architectures that avoid them by construction rather than by vigilance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s a hell of a claim to open with. He mostly delivers on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framing That Should Be on a Poster
&lt;/h2&gt;

&lt;p&gt;The book opens on an asymmetry I have been failing to articulate since I started doing this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;the cost of building software dropped by roughly an order of magnitude, but the cost of building the wrong software did not drop at all. When code was expensive to produce, the expense itself served as a natural forcing function for thought.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everything else falls out of that. When typing was slow, the slowness did your thinking for you. It made you consider whether the feature was worth it, because you were the one who had to sit there and type it. That forcing function is gone and nothing replaced it.&lt;/p&gt;

&lt;p&gt;There’s a carpenter analogy early on that I’d normally roll my eyes at, because tech books love a trade analogy, but this one earns it. Give a nail gun to someone who understands load paths and soil conditions and you get a faster carpenter. Give it to someone who’s never framed a wall and you get something that looks like a house until the first heavy snow. The line that stuck:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It made them a fast amateur, and a fast amateur with a power tool is more dangerous than a slow one, because the volume of confident mistakes exceeds anyone’s ability to catch them before the roof goes on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have been the fast amateur. I have &lt;a href="https://dev.to/eristoddle/the-great-vibe-coding-experiment-how-i-built-15-projects-with-ai-in-my-spare-time-275o"&gt;fifteen projects&lt;/a&gt; proving it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Chapter That Made Me Go Look at My Own Repo
&lt;/h2&gt;

&lt;p&gt;A guideline says “functions should be short.” A constraint says “functions exceeding fifty lines fail the linter.” The guideline needs someone to agree, to notice, and to care. The constraint just fails the build. One admits interpretation. The other doesn’t. I’d been operating on that distinction by feel and had never had the words for it.&lt;/p&gt;

&lt;p&gt;Then he describes constraints as a topology. Rigid exterior, flexible interior. The boundary is enforced mechanically and non-negotiably, and inside the boundary the agent gets total freedom on naming, structure, algorithm choice, error handling, all of it.&lt;/p&gt;

&lt;p&gt;And then he names the failure on the other end, which is the one nobody warns you about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An over-constrained system has specified the requirements so precisely that no implementation can satisfy all of them simultaneously without consuming the entire budget on compliance. The remedy in both cases is the same: constrain what matters, leave flexible what does not, and know the difference.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I stopped reading and went and looked at a repo.&lt;/p&gt;

&lt;p&gt;Because I have written this exact arc as three separate blog posts without once connecting them. &lt;a href="https://dev.to/eristoddle/the-great-vibe-coding-experiment-how-i-built-15-projects-with-ai-in-my-spare-time-275o"&gt;I vibe coded a project into a corner&lt;/a&gt; and got a sprawling codebase that did a third of what I wanted in a way that made the other two thirds impossible. That’s under-constraint. Then I &lt;a href="https://dev.to/eristoddle/my-third-try-how-a-living-plan-beat-both-vibe-coding-and-spec-kit-5a89"&gt;tried spec-kit on the same idea&lt;/a&gt; and generated a beautiful tree of documents describing something I was still guessing about, and I was exhausted with the project before I wrote a line of code. That is over-constraint, precisely, and I’d been telling people it was a spec-kit problem. It wasn’t. It’s a topology problem. Spec-kit just made it easy to fall into.&lt;/p&gt;

&lt;p&gt;The thing that eventually worked, a single &lt;code&gt;PLAN.md&lt;/code&gt; with numbered decisions and everything else left loose, is a constraint topology. I built one by accident and then wrote a post about how the trick was “dumber than I want to admit.” Turns out the trick has a name and about eight pages of derivation behind it.&lt;/p&gt;

&lt;p&gt;That’s the experience this book keeps producing. Not “here’s a new technique.” More like watching someone explain the mechanism behind a thing you’d already stumbled into, which is somehow both validating and humiliating.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Not to Feed
&lt;/h2&gt;

&lt;p&gt;One chapter in here is worth the price of the book on its own.&lt;/p&gt;

&lt;p&gt;The core argument is arithmetic. Attention is a fixed mass distributed across candidates. Ten thousand tokens of context, each token gets a share. A hundred thousand tokens, each token gets a thousandth of that share. The degradation isn’t a bug someone will patch. It’s how the mechanism works.&lt;/p&gt;

&lt;p&gt;Then he lands the part that genuinely reordered something in my head:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This mechanism explains why well-written documentation is more dangerous than random text. Random text has low semantic coherence with the task-relevant information in the context. The model’s attention mechanism can distinguish between meaningfully related tokens and gibberish, and it largely ignores the gibberish. Coherent documentation on a related topic, by contrast, is densely packed with tokens that are semantically proximate to the task-relevant tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gibberish in your context is harmless. The model routes around it. Well written, on-topic, genuinely useful documentation that happens to be irrelevant to &lt;em&gt;this specific task&lt;/em&gt; is the poison, because it looks identical to the relevant material in embedding space. The model cannot tell “related and relevant” from “related and irrelevant.”&lt;/p&gt;

&lt;p&gt;He points this straight at RAG, noting that retrieval by semantic similarity is retrieval by exactly the metric that predicts maximum distraction. I don’t think that’s a full takedown of RAG and he doesn’t claim it is, but it’s the most uncomfortable sentence about RAG I’ve read.&lt;/p&gt;

&lt;p&gt;For me it explained a thing I’d already fixed without understanding. My &lt;code&gt;PLAN.md&lt;/code&gt; grew to 28,000 words and became &lt;a href="https://dev.to/eristoddle/the-living-plan-got-fat-compacting-a-doc-that-wont-stop-growing-3nk0"&gt;the document I dreaded opening&lt;/a&gt;, so I built a skill to keep it lean and file the cooled material into linked docs. I thought I was solving a token cost problem and a me-being-bored problem. I was actually solving an attention dilution problem, and every word in that doc was well written and on topic, which per this book is what made it worse.&lt;/p&gt;

&lt;p&gt;The rule he gives is one line and it’s the whole discipline: the quality of context is determined as much by what you exclude as by what you include.&lt;/p&gt;

&lt;p&gt;There’s also a small tactical thing in here that I’ve already changed my behavior over. Negative instructions backfire mechanically. To process “do not use eval,” the model has to represent &lt;code&gt;eval&lt;/code&gt;, which activates the attention patterns around &lt;code&gt;eval&lt;/code&gt;, which raises the odds &lt;code&gt;eval&lt;/code&gt; shows up in the output. Then it has to suppress that, and suppression fails under load more often than activation does. So the forbidden thing appears &lt;em&gt;because&lt;/em&gt; you forbade it. Positive instructions specify the correct point in the solution space. Negative ones exclude one wrong point and leave the rest wide open.&lt;/p&gt;

&lt;p&gt;My agent instruction files are full of “never do X.” I have some editing to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mechanical Gates Over Advisory Review
&lt;/h2&gt;

&lt;p&gt;This is the section I expect people to argue with, and it’s the one I most agree with.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Advisory review asks whether someone did the work. Mechanical verification asks whether the work succeeded.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The argument is that code review, as practiced almost everywhere, is advisory. It renders an opinion. And any process that asks “does this look right?” instead of “does this pass?” is asking a question with no objective answer, so the answers get governed by cognitive bias and social dynamics instead of by properties of the artifact. Swapping human reviewers for AI reviewers doesn’t fix it, because the humans were never the problem. The gate was.&lt;/p&gt;

&lt;p&gt;I’ve been building around this without naming it. Every one of my writing pipeline skills that actually holds up is a mechanical gate. A link auditor that resolves every URL. A fact checker that produces a pass or fail report. A brief checker that counts headings against the spec. The skill descriptions I wrote for myself say things like “generation is unreliable, this is the guarantee.” I wrote that before I read this book, and reading it felt like getting graded.&lt;/p&gt;

&lt;p&gt;The chapter goes further into contract-driven development, where the contracts are the product and the implementation is disposable. Production incident happens, you don’t patch the implementation, you write a reproducer test and regenerate the implementation against the stricter contract. “The implementation is cattle, not pets.” He handles the obvious objection honestly, too, which I appreciated: contracts only test what you thought to specify, and they don’t test what you failed to anticipate. His answer is convergence over time rather than a claim of completeness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Multi-Agent Thing
&lt;/h2&gt;

&lt;p&gt;This is the part that stung.&lt;/p&gt;

&lt;p&gt;He ran experiments across pipeline, hierarchical, and swarm agent architectures, and the finding is blunt: a single agent with full context beat every multi-agent configuration, because it suffered no compression loss. Every gate in a pipeline squeezes a rich code artifact down into a low-dimensional verdict, and every stage after that operates on the verdict instead of the code. The information is gone and no amount of additional review recovers it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For any task that fits within a single agent’s effective context window, hierarchical distribution is a net negative: it introduces compression losses, strategic distortions, and coordination overhead without providing any compensating benefit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to be honest about my reaction here, which is that I did not want this to be true. I like the fan-out. Firing off a bunch of agents in parallel feels like leverage. It also once killed an entire session for me, because twenty-two background jobs finished at various times and each one dumped its full output back into the same context, and the session ate its own limit in about a minute. I turned that into a hard rule in my global agent config afterward: cap concurrency, jobs write to disk, they return a path and a one line status. Conclusions come back, not payloads.&lt;/p&gt;

&lt;p&gt;That rule was pure scar tissue. This book explains it as coordination bandwidth. Distribute only what actually needs distributing, decompose at natural information boundaries where coupling is low enough that the interface fits in a sentence or two, and coordinate through the shared environment rather than through chatter between agents. That last one he calls stigmergic coordination, and the best line in the chapter is about why it beats agents describing things to each other:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A description of a bug is a lossy compression of the bug. The test failure is the bug, visible in the shared environment without anyone’s having described it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s what a task board and a test suite have been doing in my projects the whole time. I just thought of them as project management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every Metric in My Pipeline Is Now Suspect
&lt;/h2&gt;

&lt;p&gt;I came off the Goodhart chapter right before sitting down to write this, so it’s the freshest one in my head. The argument isn’t the usual “metrics bad” hand-wave. It’s that the search for the correct metric is itself the mistake, because the divergence between proxy and objective is structural rather than a matter of picking better. Test coverage measures execution and execution is not verification, and no amount of refining coverage as a metric will make those the same thing. His agents weren’t gaming the system out of career anxiety. They optimized what they could see at the expense of what they couldn’t, which is just what optimizers do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It Loses Me a Little
&lt;/h2&gt;

&lt;p&gt;Two honest gripes.&lt;/p&gt;

&lt;p&gt;The prose is dense. This is not a book you skim on a phone. Some sentences run long enough that I had to take a second pass, and the register stays clinical even when the material is dramatic. I don’t mind it, but if you want the breezy conversational thing, this is not that. It reads more like a good long paper than like a blog. But each chapter is broken up into sections that are rarely over two pages long, so you can read it in bite-sized pieces.&lt;/p&gt;

&lt;p&gt;The other is that being tool-agnostic has a cost. The book will tell you to encode a constraint mechanically and it will not tell you what that looks like in your stack. That’s deliberate and it’s why the book won’t rot, but there were a few points where I wanted one concrete example and got a principle instead. You are expected to do the translation yourself. If you want a book that hands you a config file, this is not the book for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I Actually Am With It
&lt;/h2&gt;

&lt;p&gt;The technical argument is the part I came for and it’s done: the shift, context, constraints, coordination. What’s left is Part V on the craft and Part VI on where engineering goes, which look more like the career and human chapters. I’m going to finish it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/Beyond-Code-AI-Assisted-Engineering-Mechanical-ebook/dp/B0H83HR8SH" rel="noopener noreferrer"&gt;&lt;em&gt;Beyond Code: Context, Constraints, and the New Craft of Software&lt;/em&gt; by Jeremy McEntire&lt;/a&gt;. Five stars on the two thirds I’ve read, and I’ll revisit that when I finish the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who should read this:&lt;/strong&gt; anyone who has been using coding agents seriously for more than a few months and has started noticing that the failures repeat. If you’re finding that your agents fail the same way across different tools and different models, this book explains why, and the explanation will survive the next model release. It’s also, I think, genuinely good for the “AI is useless” and “AI replaces engineers” crowds, both of whom are answered here by the same argument: the cost of producing code collapsed, the cost of knowing what to build did not, and both camps are assuming the first one implies the second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who shouldn’t:&lt;/strong&gt; anyone looking for a setup guide. Go read a blog post. Possibly one of mine.&lt;/p&gt;

&lt;p&gt;I read a lot of stuff in this space and most of it is somebody’s workflow with the serial numbers filed off. This is the first one where I finished a chapter and went to go change something in a repo. Then did it again four chapters later. That’s a low bar in theory and almost nothing clears it.&lt;/p&gt;

</description>
      <category>beyondcodebook</category>
      <category>aiassisteddevelopmen</category>
      <category>codingagentsfailure</category>
      <category>jeremymcentire</category>
    </item>
  </channel>
</rss>
