<?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: NIRMEET TRIVEDI</title>
    <description>The latest articles on DEV Community by NIRMEET TRIVEDI (@nirmeet_trivedi_07bf0d38f).</description>
    <link>https://dev.to/nirmeet_trivedi_07bf0d38f</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%2F4113973%2F55276c5b-8907-4ee1-9571-df62565c8f0d.png</url>
      <title>DEV Community: NIRMEET TRIVEDI</title>
      <link>https://dev.to/nirmeet_trivedi_07bf0d38f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nirmeet_trivedi_07bf0d38f"/>
    <language>en</language>
    <item>
      <title>I audited my own product and found it never actually worked for its own core use case</title>
      <dc:creator>NIRMEET TRIVEDI</dc:creator>
      <pubDate>Sat, 12 Sep 2026 04:57:22 +0000</pubDate>
      <link>https://dev.to/nirmeet_trivedi_07bf0d38f/i-audited-my-own-product-and-found-it-never-actually-worked-for-its-own-core-use-case-498l</link>
      <guid>https://dev.to/nirmeet_trivedi_07bf0d38f/i-audited-my-own-product-and-found-it-never-actually-worked-for-its-own-core-use-case-498l</guid>
      <description>&lt;p&gt;I built &lt;a href="https://trymeanwhile.online" rel="noopener noreferrer"&gt;Meanwhile&lt;/a&gt;, a status line for Claude Code, Copilot CLI, and VS Code. Most of the time it shows a quiet tip. Sometimes it shows a clearly-labeled "(sponsored)" line instead, and when that happens half of what the sponsor paid goes back to the developer.&lt;/p&gt;

&lt;p&gt;This week I actually sat down and audited my own code end to end instead of just checking install counts. What I found wasn't great: the VS Code extension had been silently broken for the exact use case it exists for, since the day it shipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 1: the extension required a keystroke every 30 seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ACTIVITY_FRESHNESS_MS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;poll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;windowFocused&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;focused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recentlyActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lastActivityAt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;ACTIVITY_FRESHNESS_MS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;windowFocused&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;recentlyActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...fetch and bill a line...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;lastActivityAt&lt;/code&gt; only updated on a real document edit. The moment you fire off an agent and take your hands off the keyboard to let it think, &lt;code&gt;recentlyActive&lt;/code&gt; goes false within 30 seconds and the extension goes completely dark. That's the exact window the whole product exists to monetize.&lt;/p&gt;

&lt;p&gt;Fix: track presence more broadly (tab switches, cursor movement, regaining window focus, not just edits), and widen the window to 5 minutes to actually match how long an agent turn runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 2: even a live poll got flagged as fake
&lt;/h2&gt;

&lt;p&gt;Independently, the server had its own gate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sessionProgressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;baseline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For VS Code, &lt;code&gt;tokens&lt;/code&gt; is mapped to the editor's own edit count. Requiring it to strictly increase makes sense for Claude Code (a real session's cost/tokens always climb turn over turn) but is exactly backwards for VS Code: edit count is &lt;em&gt;supposed&lt;/em&gt; to plateau while you're waiting on an agent. So even after fixing bug 1, a genuinely live poll during a wait still got silently discarded as "looks like a faked ping."&lt;/p&gt;

&lt;p&gt;Two independent bugs, stacked, both silently killing the same use case. Fixed by trusting a live poll within the same session (matched by session ID) instead of requiring a number that has no reason to move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 3: Copilot CLI only ever billed the first turn of a session
&lt;/h2&gt;

&lt;p&gt;Copilot CLI's hook payload never sends cost or token data at all, just a &lt;code&gt;session_id&lt;/code&gt; — and unlike Claude Code, that id doesn't change per turn, it's scoped to the whole CLI session. The server's fallback logic assumed a changing session id was the signal of real progression. Since Copilot's never changes within a session, every turn after the first billed $0, silently, for as long as the extension has existed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The smaller stuff
&lt;/h2&gt;

&lt;p&gt;Also found and fixed while in there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/network-stats&lt;/code&gt; was doing a full sequential KV scan (600+ reads) on every request — replaced with a self-seeding Durable Object counter, now O(1)&lt;/li&gt;
&lt;li&gt;A daily payout cron was writing install state directly to KV, bypassing the Durable Object that's supposed to be authoritative — a real double-payout risk&lt;/li&gt;
&lt;li&gt;Abandoned advertiser checkouts were staying in a shared index forever, costing a KV read on every single status-line poll from every user&lt;/li&gt;
&lt;li&gt;The Windows installer was missing a required config field the macOS/Linux one had&lt;/li&gt;
&lt;li&gt;All three client scripts would hang forever if you ran them by hand to test (blocking on stdin with no TTY check)&lt;/li&gt;
&lt;li&gt;The direct extension download on the site was still serving a build with bug 1 in it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is retroactive marketing spin — if you installed the VS Code extension before this week and it felt dead, that was real, not you. It's fixed now (0.1.7, live on Open VSX).&lt;/p&gt;

&lt;p&gt;I don't have big usage numbers to show off here. What I have is a real list of specific, embarrassing bugs, found by actually reading the code instead of trusting a dashboard, and fixed. If that's useful to anyone auditing their own "is this actually doing what I think it's doing" assumptions, that's the whole point of writing this up.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>debugging</category>
      <category>softwaredevelopment</category>
      <category>startup</category>
    </item>
    <item>
      <title>Your Cloudflare Workers KV rate limiter is probably attacking itself</title>
      <dc:creator>NIRMEET TRIVEDI</dc:creator>
      <pubDate>Thu, 10 Sep 2026 05:36:17 +0000</pubDate>
      <link>https://dev.to/nirmeet_trivedi_07bf0d38f/your-cloudflare-workers-kv-rate-limiter-is-probably-attacking-itself-2nb1</link>
      <guid>https://dev.to/nirmeet_trivedi_07bf0d38f/your-cloudflare-workers-kv-rate-limiter-is-probably-attacking-itself-2nb1</guid>
      <description>&lt;p&gt;I ship a small Cloudflare Worker (a Claude Code status line that pays users a cut of disclosed sponsor revenue -- not the point of this post, just context for where the traffic pattern came from). Every install polls &lt;code&gt;/line&lt;/code&gt; every 10-20 seconds while the user is coding. That's a lot of requests hitting one Worker.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup that seemed fine
&lt;/h2&gt;

&lt;p&gt;Rate limiting a Worker endpoint by install ID looks like a one-liner with KV:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkLineRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;installId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`ratelimit:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;installId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INSTALLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;LIMIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INSTALLS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expirationTtl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WINDOW_SECONDS&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This worked in testing. It broke in production, and not because of an attack -- just real usage at real scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it actually breaks
&lt;/h2&gt;

&lt;p&gt;Workers KV on the free plan has an account-wide cap: 100,000 &lt;code&gt;get()&lt;/code&gt; reads per day, not per namespace, not per key. Every single &lt;code&gt;/line&lt;/code&gt; call was doing a &lt;code&gt;get()&lt;/code&gt; just to check the rate limit, before it ever touched the actual install data. At normal polling frequency across a few hundred concurrent installs, that hot-path read alone was enough to burn through the daily quota -- and once it's gone, it's gone until midnight UTC. Every KV &lt;code&gt;get()&lt;/code&gt; anywhere in the account starts failing with a hard error, including reads that have nothing to do with rate limiting.&lt;/p&gt;

&lt;p&gt;The failure mode is brutal because it's silent until it isn't: everything works fine right up until the exact moment the account-wide counter ticks over, and then every &lt;code&gt;/line&lt;/code&gt; call in production starts 500ing at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: stop asking KV a question the cache API can already answer
&lt;/h2&gt;

&lt;p&gt;The rate limit check doesn't need durability. It doesn't need to survive a Worker restart. It just needs to answer "has this install called recently" for a few seconds, cheaply, at massive read volume. That's exactly what the platform's own edge cache is for, and unlike KV, &lt;code&gt;caches.default&lt;/code&gt; reads don't count against any daily read quota at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkLineRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;installId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://ratelimit.internal/line/install/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;installId&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;LIMIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cache-control&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`max-age=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;WINDOW_SECONDS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// fail open: a rate-limit check failing should never break the real request&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same interface, same call site, zero KV reads for this path. The &lt;code&gt;try/catch&lt;/code&gt; matters as much as the cache swap: a rate limiter is a defensive layer, and defensive layers should fail open, not become a second way for the app to go down.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that isn't about caching at all
&lt;/h2&gt;

&lt;p&gt;Fixing the hot path wasn't enough on its own, because the actual install &lt;em&gt;data&lt;/em&gt; reads (not the rate limit, the real per-user state) were still hitting KV directly on every call. I moved those onto a Durable Object, one instance per install (&lt;code&gt;idFromName(installId)&lt;/code&gt;), so KV is only touched once -- on that instance's true cold start -- and every call after that is served from the DO's own durable storage. The DO mirrors writes back to KV asynchronously so anything else that reads &lt;code&gt;install:&amp;lt;id&amp;gt;&lt;/code&gt; directly out of KV (an admin dashboard, a cron job) still sees current data without knowing the DO exists.&lt;/p&gt;

&lt;p&gt;The general shape of the fix, not just for this bug: if something is read on every request and doesn't strictly need cross-region strong consistency, it probably shouldn't be sharing a quota with your actual source-of-truth reads. Splitting "is this allowed" from "what's the data" onto different storage tiers means a hot path can run as hot as it wants without threatening to take down everything else sharing that account.&lt;/p&gt;

</description>
      <category>cloudflare</category>
      <category>serverless</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I built a status line that pays you while your AI coding agent thinks</title>
      <dc:creator>NIRMEET TRIVEDI</dc:creator>
      <pubDate>Mon, 07 Sep 2026 12:53:41 +0000</pubDate>
      <link>https://dev.to/nirmeet_trivedi_07bf0d38f/i-built-a-status-line-that-pays-you-while-your-ai-coding-agent-thinks-bn6</link>
      <guid>https://dev.to/nirmeet_trivedi_07bf0d38f/i-built-a-status-line-that-pays-you-while-your-ai-coding-agent-thinks-bn6</guid>
      <description>&lt;p&gt;I'm 14, and I got tired of watching Claude Code's spinner sit there doing nothing for money. So I built Meanwhile -- a status line that shows a clearly disclosed sponsor line while your AI agent is thinking, and pays you a real cut for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx trymeanwhile&lt;/code&gt; wires into Claude Code's (or Copilot CLI's) own supported &lt;code&gt;statusLine&lt;/code&gt; setting -- nothing patches your machine. While your agent is working, the line rotates between plain tips and occasional sponsor lines. Every sponsor line is labeled as sponsored, always. You split what it earns, 50/50, paid out automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's built
&lt;/h2&gt;

&lt;p&gt;The backend is entirely Cloudflare Workers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Durable Objects&lt;/strong&gt; serialize concurrent impression-count writes. I stress-tested plain KV read-modify-write under concurrent requests and it was losing 18 out of 20 increments -- classic race condition. A Durable Object per ad campaign (via &lt;code&gt;idFromName&lt;/code&gt;) fixed that completely, since it processes requests for that campaign one at a time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workers AI&lt;/strong&gt; (&lt;code&gt;@cf/meta/llama-3.2-3b-instruct&lt;/code&gt;) generates a chunk of the non-sponsor tip lines, with a hard timeout fallback so a slow model call never blocks your status line from rendering.&lt;/li&gt;
&lt;li&gt;KV handles per-install state, rate-limiting, and session baselines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The billing signal
&lt;/h2&gt;

&lt;p&gt;The whole thing only bills a line if it actually stayed on screen for 10+ seconds -- so it's tied to real thinking time, not just an API call firing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx trymeanwhile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your tool and you're in. Check what you've earned with &lt;code&gt;npx trymeanwhile claim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Live at trymeanwhile.online. Would genuinely love feedback, especially from anyone who's dealt with concurrency bugs like the KV one above -- curious if there's a cleaner pattern I'm missing.&lt;/p&gt;

</description>
      <category>cloudflare</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
