<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Advik's Dev Blog]]></title><description><![CDATA[Advik's Dev Blog]]></description><link>https://advik28.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 31 Oct 2026 23:36:44 GMT</lastBuildDate><atom:link href="https://advik28.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I almost burned ₹4,000 on Claude API overnight — so I built llm-cost-guard]]></title><description><![CDATA[Real-time cost middleware for LLM APIs. Set budgets, get alerts, stop runaway Claude/OpenAI spend before it happens.]]></description><link>https://advik28.hashnode.dev/i-almost-burned-4-000-on-claude-api-overnight-so-i-built-llm-cost-guard</link><guid isPermaLink="true">https://advik28.hashnode.dev/i-almost-burned-4-000-on-claude-api-overnight-so-i-built-llm-cost-guard</guid><category><![CDATA[llm]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[webdev]]></category><category><![CDATA[openai]]></category><dc:creator><![CDATA[Advik]]></dc:creator><pubDate>Sat, 13 Jun 2026 18:21:38 GMT</pubDate><content:encoded><![CDATA[<p>I almost burned ₹4,000 on Claude API overnight — so I built llm-cost-guard Last month I wrote what I thought was a harmless script.</p>
<p>Batch-process 847 product descriptions through Claude. Summarize each one. Save to a CSV. Ship it and go to bed.</p>
<p>The loop looked fine. Error handling was there. Retries were capped. I felt responsible.</p>
<p>I woke up to a Slack ping from my own logging bot — not because anything crashed, but because something succeeded way too much.</p>
<p>₹4,000 gone. Overnight. On a side project.</p>
<p>The loop hadn't infinite-looped in the traditional sense. It had expensive-looped. A retry bug on malformed responses meant some items got hit 3–4 times. A few prompts were longer than I estimated. And I had zero visibility into running spend while it was happening.</p>
<p>I stared at the Anthropic dashboard like it was a crime scene.</p>
<p>Why Anthropic billing alerts don't cut it Anthropic does have billing alerts. They're useful — for finance, eventually.</p>
<p>But they're not a runtime guardrail:</p>
<p>Delayed — you find out after the damage, not mid-request Account-level — one rogue script takes down your whole API budget Non-blocking — an email doesn't stop a loop that's already running What I actually needed was something that sits inside my code and says: "Stop. You've hit your limit. Right now."</p>
<p>Not tomorrow. Not at invoice time. Before request #400 burns another ₹500.</p>
<p>What llm-cost-guard does It's a drop-in wrapper for your existing LLM client. One line. No SDK rewrite.</p>
<p>import Anthropic from "@anthropic-ai/sdk"; import { guard } from "@advik1228/llm-cost-guard"; const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }); const client = guard(anthropic, { dailyLimit: 5, onLimit: "throw" }); // Use client exactly like before — same API, same methods const response = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, messages: [{ role: "user", content: "Summarize this..." }], }); That's it. If today's spend crosses $5, the next call throws. The loop dies. Your wallet survives.</p>
<p>You can also set monthly caps, per-request limits, per-user budgets, webhook alerts, and streaming support — but the core idea is dead simple: wrap, limit, block.</p>
<p>How it works under the hood No monkey-patching. No forked SDK.</p>
<p>llm-cost-guard uses a JavaScript Proxy to intercept calls to messages.create (Anthropic), chat.completions.create (OpenAI), and Gemini's generateContent.</p>
<p>When a call completes, it reads the real token counts from the API response — usage.input_tokens, usage.output_tokens, etc. Not tiktoken guesses. The provider already counted them; we just listen.</p>
<p>Then it:</p>
<p>Calculates cost in USD from a built-in pricing table Increments daily/monthly/user spend in memory or Redis Checks your limits Throws, warns, or stays silent — your call For streaming, it runs a pre-flight estimate before the stream starts, passes every chunk through unchanged, and records spend when the stream finishes.</p>
<p>The Proxy pattern means your existing code doesn't change. Your types mostly don't change. You just wrap once at startup.</p>
<p>Install + quick start npm install @advik1228/llm-cost-guard Anthropic:</p>
<p>import { guard } from "@advik1228/llm-cost-guard"; const client = guard(anthropic, { dailyLimit: 5.0, warnAt: 4.0, onLimit: "throw", }); OpenAI:</p>
<p>const client = guard(openai, { dailyLimit: 10.0, perRequestLimit: 0.50, onLimit: "throw", }); Multi-tenant / production — plug in Redis so limits are shared across instances:</p>
<p>import { guard, RedisAdapter } from "@advik1228/llm-cost-guard"; const client = guard(anthropic, { dailyLimit: 100, storage: new RedisAdapter(redis), userId: req.user.id, userDailyLimit: 2.0, }); Try it — before your next overnight job I built this because I needed it to exist. Not as a SaaS pitch. Not as an observability platform. Just a small guard that sits between my code and an API that charges by the token.</p>
<p>If you've ever run a batch job and thought "this should be fine" — it probably is, until it isn't.</p>
<p>Star the repo if this saves you once. Install it before your next loop. Set a daily limit low enough to hurt your ego but not your bank account.</p>
<p>GitHub: <a href="https://github.com/advikhingmire12-oss/llm-cost-guard">https://github.com/advikhingmire12-oss/llm-cost-guard</a> npm: <a href="https://www.npmjs.com/package/@advik1228/llm-cost-guard">https://www.npmjs.com/package/@advik1228/llm-cost-guard</a></p>
]]></content:encoded></item></channel></rss>