<?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: John Medina</title>
    <description>The latest articles on DEV Community by John Medina (@amedinat).</description>
    <link>https://dev.to/amedinat</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%2F3854284%2F73b7fb73-f118-4d37-b5a7-37581d43bd0a.png</url>
      <title>DEV Community: John Medina</title>
      <link>https://dev.to/amedinat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amedinat"/>
    <language>en</language>
    <item>
      <title>Your LLM Budget Alerts Won't Save You. Here's Why.</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 07 Sep 2026 14:06:08 +0000</pubDate>
      <link>https://dev.to/amedinat/your-llm-budget-alerts-wont-save-you-heres-why-4e7d</link>
      <guid>https://dev.to/amedinat/your-llm-budget-alerts-wont-save-you-heres-why-4e7d</guid>
      <description>&lt;p&gt;You get the email at 2 AM. Your cloud provider, with a tone of forced helpfulness, informs you you've burned through 80% of your monthly LLM budget. In the first week.&lt;/p&gt;

&lt;p&gt;"No problem," you think. "I have budget alerts for this." But the damage is done. The runaway agent, the one you tasked with summarizing customer support tickets, decided to recursively summarize its own summaries. For 12 hours straight.&lt;/p&gt;

&lt;p&gt;The truth is, the simple budget alerts we all set up are a trap. They give us a false sense of security in the age of agentic AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Agentic Spend Problem
&lt;/h3&gt;

&lt;p&gt;A single user click can now trigger a cascade of LLM calls. An agent might read a document, then decide to search the web for context, then summarize its findings, then translate them. That's four API calls, not one. Your old-school "dollars per day" alert is blind to this. It only sees the total. It can't tell you that &lt;em&gt;one specific user's request&lt;/em&gt; just cost you $50.&lt;/p&gt;

&lt;p&gt;This is the new reality of "agentic spend." It's unpredictable, spiky, and hard to trace back to a single cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  From Monitoring to Attribution
&lt;/h3&gt;

&lt;p&gt;The only way to control these costs is to move from passive monitoring to active attribution. You need to know, in real-time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Which user&lt;/strong&gt; is generating the most cost?&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Which agent or feature&lt;/strong&gt; is the most expensive?&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Which model&lt;/strong&gt; is eating up your budget?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this level of granularity, you're flying blind. You can't optimize what you can't see.&lt;/p&gt;

&lt;p&gt;This is why I built LLMeter. It's an open-source dashboard that gives you per-user, per-model, and per-day cost attribution. It's not just another alert system. It's a tool for understanding where your money is going, so you can stop the bleeding before it starts.&lt;/p&gt;

&lt;p&gt;Fwiw, a simple dashboard showing real-time spend per user has been more effective for us than any alert we've ever set up. The game has changed. Your tools need to change too.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>3 Costly Mistakes I Made With the OpenAI API (So You Don't Have To)</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 31 Aug 2026 14:06:17 +0000</pubDate>
      <link>https://dev.to/amedinat/3-costly-mistakes-i-made-with-the-openai-api-so-you-dont-have-to-4pa3</link>
      <guid>https://dev.to/amedinat/3-costly-mistakes-i-made-with-the-openai-api-so-you-dont-have-to-4pa3</guid>
      <description>&lt;p&gt;You get the first bill from OpenAI and it's 10x what you expected. We've all been there.&lt;/p&gt;

&lt;p&gt;It's not about the cost of a single call. It's about the thousands of calls you didn't know you were making. Here are three traps I fell into.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Forgetting about Temperature and Max Tokens
&lt;/h3&gt;

&lt;p&gt;This is the classic. You're testing in the playground, &lt;code&gt;temperature&lt;/code&gt; is at 0.7 for creative outputs, and &lt;code&gt;max_tokens&lt;/code&gt; is wide open. Works great. Then you push it to production.&lt;/p&gt;

&lt;p&gt;Suddenly, a simple summarization task that should take 200 tokens is regularly using 1500 because the model is getting creative with its output length. Every. Single. Time. For high-volume tasks, this adds up faster than you can blink.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Set &lt;code&gt;max_tokens&lt;/code&gt; to a sane, hard limit for your specific use case. And unless you &lt;em&gt;need&lt;/em&gt; creativity, turn &lt;code&gt;temperature&lt;/code&gt; down to 0.1 or 0.2. Your wallet will thank you.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Not Tracking Costs Per User
&lt;/h3&gt;

&lt;p&gt;When you're starting out, all API calls go through a single key. It's fine. Until you have your first power user.&lt;/p&gt;

&lt;p&gt;One user starts running complex reports, another is just doing simple lookups. But your bill just shows one big number. You have no idea who is costing you money or who your most valuable (or expensive) users are. You can't bill them, you can't limit them, you can't do anything. You're flying blind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; From day one, attribute every single API call to a user ID. Don't just log it somewhere—track it. You need to know which users are driving your costs. It's not optional if you plan to build a business on this.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ignoring the Model Version
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;gpt-4&lt;/code&gt; is not &lt;code&gt;gpt-4-turbo&lt;/code&gt;. The costs are wildly different. It's easy to just use the "latest and greatest" model for everything during development. But moving to production with that mindset is a recipe for a financial shock.&lt;/p&gt;

&lt;p&gt;I once had a background job running on the full &lt;code&gt;gpt-4&lt;/code&gt; model for a simple text classification task. It worked, sure. But &lt;code&gt;gpt-3.5-turbo&lt;/code&gt; would have been 10x cheaper and 99% as effective. The difference was thousands of dollars over a month for a non-critical feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Audit your model usage. Use the most powerful models only where absolutely necessary. For everything else, find the cheapest model that gets the job done. This requires constant monitoring.&lt;/p&gt;




&lt;p&gt;I got so frustrated with flying blind on costs that I built a tool to fix it. It's an open-source dashboard called LLMeter. It hooks into OpenAI (and Anthropic, DeepSeek, etc.) and gives me a real-time view of costs per model, per user, per day. It's how I caught that &lt;code&gt;gpt-4&lt;/code&gt; issue.&lt;/p&gt;

&lt;p&gt;You can check it out at &lt;a href="https://llmeter.org" rel="noopener noreferrer"&gt;https://llmeter.org&lt;/a&gt; if you're tired of guessing.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>3 Ways to Track Anthropic API Costs (And Why the Console Isn't Enough)</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 24 Aug 2026 14:06:40 +0000</pubDate>
      <link>https://dev.to/amedinat/3-ways-to-track-anthropic-api-costs-and-why-the-console-isnt-enough-3i1c</link>
      <guid>https://dev.to/amedinat/3-ways-to-track-anthropic-api-costs-and-why-the-console-isnt-enough-3i1c</guid>
      <description>&lt;p&gt;PLATAFORMA: Dev.to&lt;/p&gt;

&lt;p&gt;The Anthropic console gives you one number: your monthly bill. If you're building a multi-tenant app on top of Claude, that's not nearly enough. You need to know which customers are costing you the most, which features are driving that cost, and how to spot a runaway bill before it happens.&lt;/p&gt;

&lt;p&gt;Here are three ways to get more granular cost data, from the simple to the more robust.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Usage API: A Good First Step
&lt;/h3&gt;

&lt;p&gt;Anthropic's Usage API is a solid starting point. You can query it to get cost data broken down by &lt;code&gt;user_id&lt;/code&gt; (if you're creating a key per user, which I don't recommend), &lt;code&gt;model&lt;/code&gt;, and &lt;code&gt;date&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's better than nothing, but it's still reactive. You're looking at costs that have already been incurred.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The SDK Wrapper: Proactive, But More Work
&lt;/h3&gt;

&lt;p&gt;A better approach is to wrap the Anthropic SDK. This lets you intercept every API call, log the token counts from the response along with your own internal &lt;code&gt;customer_id&lt;/code&gt; or &lt;code&gt;feature_id&lt;/code&gt;, and then store that data in your own database.&lt;/p&gt;

&lt;p&gt;This is a more proactive approach. You can build your own real-time dashboards and set up alerts based on your own business logic. The downside is that you have to build and maintain it yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Unified, Proxyless Monitoring: The Best of Both Worlds
&lt;/h3&gt;

&lt;p&gt;The ideal solution is a dedicated, open-source tool that handles this for you. That's why I built LLMeter.&lt;/p&gt;

&lt;p&gt;LLMeter uses async, out-of-band monitoring to track your costs without adding any latency to your API calls. It gives you a unified dashboard for all your LLM providers (not just Anthropic), with per-user and per-feature cost attribution out of the box.&lt;/p&gt;

&lt;p&gt;You can self-host it, so your data never leaves your infrastructure.&lt;/p&gt;

&lt;p&gt;The Anthropic console is fine for a hobby project. But if you're building a business on top of their API, you need to own your cost data. Don't wait for the end-of-month surprise.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>The 'AI Trust Tax': The Hidden 30% You're Paying on Every LLM Call</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 17 Aug 2026 14:08:11 +0000</pubDate>
      <link>https://dev.to/amedinat/the-ai-trust-tax-the-hidden-30-youre-paying-on-every-llm-call-2c3d</link>
      <guid>https://dev.to/amedinat/the-ai-trust-tax-the-hidden-30-youre-paying-on-every-llm-call-2c3d</guid>
      <description>&lt;p&gt;PLATAFORMA: Dev.to&lt;/p&gt;

&lt;p&gt;You've calculated your LLM costs down to the last token. You know the price of GPT-4o vs. Sonnet 3.5. You've optimized your prompts.&lt;/p&gt;

&lt;p&gt;So why is your bill still 30% higher than you expected?&lt;/p&gt;

&lt;p&gt;You're paying an invisible "AI Trust Tax."&lt;/p&gt;

&lt;p&gt;This isn't about the inference cost. This is the tax you pay to make sure the model doesn't go off the rails. It's the cost of guardrail models, safety checks, evaluation calls, and moderation APIs.&lt;/p&gt;

&lt;p&gt;It's the cost of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pre-flight checks:&lt;/strong&gt; Running a prompt through a smaller, faster model (like Haiku) to check for PII or policy violations before sending it to the big, expensive model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-flight analysis:&lt;/strong&gt; Sending the model's output to a moderation API to check for hate speech or other unwanted content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red-teaming and evaluation:&lt;/strong&gt; Constantly running your prompts and outputs through evaluation pipelines to measure quality and detect regressions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are all necessary evils. You can't ship a production AI app without them. But they are also silent budget killers.&lt;/p&gt;

&lt;p&gt;The problem is that most monitoring tools only show you the cost of the final generation. They don't show you the cost of the &lt;em&gt;entire chain&lt;/em&gt; of calls that it took to produce that generation.&lt;/p&gt;

&lt;p&gt;This is where a tool that monitors &lt;em&gt;all&lt;/em&gt; your API calls becomes essential. When I was building LLMeter, I made sure it could track every single call to every provider. That's how you uncover the hidden "trust tax."&lt;/p&gt;

&lt;p&gt;Once you can see the full cost, you can start to optimize it. Maybe you can batch your moderation calls. Maybe you can run your pre-flight checks on a cheaper model.&lt;/p&gt;

&lt;p&gt;But you can't optimize what you can't see. Stop paying the invisible tax. Get a monitoring tool that shows you the whole picture.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>The Collapsing Stack: How Vendor Lock-in is Coming for Your AI-Powered Applications</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 10 Aug 2026 14:02:24 +0000</pubDate>
      <link>https://dev.to/amedinat/the-collapsing-stack-how-vendor-lock-in-is-coming-for-your-ai-powered-applications-4k96</link>
      <guid>https://dev.to/amedinat/the-collapsing-stack-how-vendor-lock-in-is-coming-for-your-ai-powered-applications-4k96</guid>
      <description>&lt;p&gt;You chose Bun for its speed, but you might be getting more than you bargained for. What happens when your runtime, your CLI, and your LLM are all owned by the same company?&lt;/p&gt;

&lt;p&gt;This is the new reality of the AI-powered stack. The lines are blurring between the tools we use to build our applications and the AI services we consume. And this "collapsing stack" is creating a new and dangerous form of vendor lock-in.&lt;/p&gt;

&lt;p&gt;When a single company controls your runtime, they can start to influence your choice of AI provider. They can offer "seamless integrations" that are anything but seamless to disentangle. They can bundle services in a way that makes it impossible to switch one component without switching them all.&lt;/p&gt;

&lt;p&gt;Think about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  What if your runtime starts making metered calls to the vendor's AI service by default?&lt;/li&gt;
&lt;li&gt;  What if your CLI tool for deploying your application also "helpfully" provisions the vendor's AI services?&lt;/li&gt;
&lt;li&gt;  What if the terms of service for your runtime are updated to include clauses about your usage of their AI services?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't just a hypothetical scenario. We're already seeing the first signs of this with Bun's rewrite in Rust by the same company that's behind the Claude models.&lt;/p&gt;

&lt;p&gt;The only way to protect yourself is to maintain control over your stack. You need to use tools that are open, interoperable, and vendor-agnostic.&lt;/p&gt;

&lt;p&gt;This is especially true for monitoring. You can't rely on your vendor's dashboard to give you an unbiased view of your costs. You need an independent tool that can monitor your usage across all your providers.&lt;/p&gt;

&lt;p&gt;That's why we built LLMeter (&lt;a href="https://llmeter.org" rel="noopener noreferrer"&gt;https://llmeter.org&lt;/a&gt;). It's an open-source, self-hosted tool that gives you a single pane of glass for all your LLM costs. It's vendor-agnostic by design.&lt;/p&gt;

&lt;p&gt;Don't let the collapsing stack lock you in. Choose your tools wisely, and maintain control of your own destiny.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>Monitor LLM Costs with Prometheus &amp; Grafana (Without a Proxy)</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:07:58 +0000</pubDate>
      <link>https://dev.to/amedinat/monitor-llm-costs-with-prometheus-grafana-without-a-proxy-2gcm</link>
      <guid>https://dev.to/amedinat/monitor-llm-costs-with-prometheus-grafana-without-a-proxy-2gcm</guid>
      <description>&lt;p&gt;PLATAFORMA: Dev.to&lt;/p&gt;

&lt;p&gt;If you're running any observability stack, you've probably got Prometheus and Grafana at the core. You've got your CPU usage, your memory, your network I/O... but what about your single biggest, most volatile line item? Your LLM bill.&lt;/p&gt;

&lt;p&gt;Getting that data into your existing dashboards is a pain. Most solutions want you to route all your traffic through their proxy, adding a point of failure and latency you don't need.&lt;/p&gt;

&lt;p&gt;It doesn't have to be that complicated.&lt;/p&gt;

&lt;p&gt;I'm a big believer in async, out-of-band monitoring. Your app should fire and forget logging events, not wait for a monitoring service to respond. This is why when I built LLMeter, I made sure it could plug into the tools you already use.&lt;/p&gt;

&lt;p&gt;Here's how you can pipe your LLM costs into Prometheus without a proxy.&lt;/p&gt;

&lt;p&gt;LLMeter exposes a &lt;code&gt;/metrics&lt;/code&gt; endpoint that Prometheus can scrape, just like it does for your other services. All you need to do is add a new job to your &lt;code&gt;prometheus.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scrape_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;llmeter'&lt;/span&gt;
    &lt;span class="na"&gt;scrape_interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15s&lt;/span&gt;
    &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;your-llmeter-instance.local:3000'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Now you can build Grafana dashboards that show your LLM costs right next to your other metrics. You can see how a spike in traffic to a certain endpoint correlates with a spike in your Anthropic bill. You can finally see the &lt;em&gt;real&lt;/em&gt; cost of that new AI feature you just shipped.&lt;/p&gt;

&lt;p&gt;This approach gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-latency monitoring:&lt;/strong&gt; Your API calls go straight to the provider, not through a third-party proxy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time visibility:&lt;/strong&gt; See your costs as they happen, not at the end of the month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unified dashboards:&lt;/strong&gt; No more context-switching between your observability stack and your LLM provider's billing page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stop flying blind. Your LLM bill is part of your infrastructure cost. It's time to start treating it that way.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>The Caching Illusion: Why Semantic Cache Won't Save Your LLM Budget</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 27 Jul 2026 14:02:57 +0000</pubDate>
      <link>https://dev.to/amedinat/the-caching-illusion-why-semantic-cache-wont-save-your-llm-budget-1ili</link>
      <guid>https://dev.to/amedinat/the-caching-illusion-why-semantic-cache-wont-save-your-llm-budget-1ili</guid>
      <description>&lt;p&gt;Everyone tells you to just drop a semantic cache in front of OpenAI or Anthropic to cut costs. I tried it. tbh, it's mostly an illusion.&lt;/p&gt;

&lt;p&gt;Here is the reality of AI agents: they don't ask the same questions twice. They inject dynamic context, timestamps, user-specific IDs, and multi-step reasoning traces into every single prompt. &lt;/p&gt;

&lt;p&gt;I looked at 50,000 requests from a basic RAG setup. The cache hit rate? 4.2%. &lt;/p&gt;

&lt;p&gt;A 4% cache hit rate doesn't save a $5k/mo bill. It just adds Redis infrastructure costs and a layer of latency you didn't need. The real problem isn't caching. The real problem is you don't know &lt;em&gt;which&lt;/em&gt; user or &lt;em&gt;which&lt;/em&gt; agent loop is burning the other 96% of the budget.&lt;/p&gt;

&lt;p&gt;If you have a multi-tenant app, your biggest risk isn't missing a cache hit. It's one power user triggering a runaway agent loop that eats your entire API quota while everyone else gets rate-limited. &lt;/p&gt;

&lt;p&gt;You need per-user cost attribution, not just a cache. &lt;/p&gt;

&lt;p&gt;I built LLMeter (&lt;a href="https://llmeter.org?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=devto-caching-illusion-llmeter" rel="noopener noreferrer"&gt;https://llmeter.org?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=devto-caching-illusion-llmeter&lt;/a&gt;) exactly for this. It's an open-source (AGPL-3.0) dashboard that tracks costs per model, per user, per day. It supports OpenAI, Anthropic, DeepSeek, and OpenRouter. &lt;/p&gt;

&lt;p&gt;Stop trying to cache dynamic agent loops. Start tracking who is actually spending your money.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>Don't Trust OpenAI's Billing Alerts Alone</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 20 Jul 2026 14:04:57 +0000</pubDate>
      <link>https://dev.to/amedinat/dont-trust-openais-billing-alerts-alone-5fg6</link>
      <guid>https://dev.to/amedinat/dont-trust-openais-billing-alerts-alone-5fg6</guid>
      <description>&lt;p&gt;PLATAFORMA: Dev.to&lt;/p&gt;

&lt;p&gt;You set a hard budget limit in your OpenAI dashboard. You think you're safe. Then at the end of the month, you get a bill for 2x what you expected.&lt;/p&gt;

&lt;p&gt;Happens all the time. Saw a few devs complaining about it again this week.&lt;/p&gt;

&lt;p&gt;The "hard limit" isn't hard. It's a notification threshold that can be minutes or even hours delayed. By the time it triggers and you get the email, a runaway script or a high-traffic feature could have already burned through a lot more cash.&lt;/p&gt;

&lt;p&gt;The issue is that usage data isn't processed in real-time. It's batched. So the dashboard you're looking at is always slightly in the past.&lt;/p&gt;

&lt;p&gt;It's not a bug, it's how their billing infra is designed. But it's a problem if you're bootstrapping or giving per-user access to an LLM feature. One user having a field day can blow your whole month's budget.&lt;/p&gt;

&lt;p&gt;The only real fix is to monitor costs on your end, request-by-request.&lt;/p&gt;

&lt;p&gt;I built a simple open-source tool, LLMeter (llmeter.org), to deal with this. It tracks costs as they happen and has its own alerting system that's much closer to real-time. It also helps attribute costs per-user or per-feature, which is something OpenAI's dash doesn't do.&lt;/p&gt;

&lt;p&gt;fwiw, whatever you use, don't rely on the official billing alerts alone for cost protection. You'll get burned eventually.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>Everyone's sleeping on the easiest 50% discount for LLM APIs</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 13 Jul 2026 14:01:44 +0000</pubDate>
      <link>https://dev.to/amedinat/everyones-sleeping-on-the-easiest-50-discount-for-llm-apis-6e9</link>
      <guid>https://dev.to/amedinat/everyones-sleeping-on-the-easiest-50-discount-for-llm-apis-6e9</guid>
      <description>&lt;p&gt;You see all these complex guides on prompt engineering, model routing, caching... all promising to shave a few percentage points off your LLM bill. They're not wrong, but they're missing the forest for the trees.&lt;/p&gt;

&lt;p&gt;OpenAI and Anthropic are literally offering a 50% discount on their most powerful models. And it seems like nobody is talking about it.&lt;/p&gt;

&lt;p&gt;It's called the Batch API.&lt;/p&gt;

&lt;p&gt;It's not new, it's not sexy, and it doesn't involve any "AI magic". It's just a different endpoint. Instead of sending requests one by one, you bundle them up and send them in a single file. 24 hours later, you get a file back with the results.&lt;/p&gt;

&lt;p&gt;The catch? It's async. Heavily async. You can't use this for a real-time chatbot. The 24-hour SLA is real.&lt;/p&gt;

&lt;p&gt;But for any non-interactive workload? It's a no-brainer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Summarizing articles for a newsletter.&lt;/li&gt;
&lt;li&gt;Generating embeddings for a RAG pipeline.&lt;/li&gt;
&lt;li&gt;Classifying user-generated content.&lt;/li&gt;
&lt;li&gt;Running batch evaluations on a new prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these tasks are perfect for batching. You're probably running them on the real-time endpoint right now and paying double for the privilege.&lt;/p&gt;

&lt;p&gt;The implementation is a bit different. You upload a JSONL file with your requests, start the batch job, and then poll for completion. It's a bit more work than a simple POST request, but it's not rocket science.&lt;/p&gt;

&lt;p&gt;We wrote a more detailed breakdown of the pricing and gotchas here: &lt;a href="https://simplifai.tools/blog/llm-batch-api-pricing" rel="noopener noreferrer"&gt;https://simplifai.tools/blog/llm-batch-api-pricing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Honestly, before you spend a week implementing a caching layer, just check if your workload can be batched. It's the most boring, most effective way to cut your LLM costs. fwiw.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>Your LLM Bill is a Ticking Time Bomb. Here's How to Defuse It.</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 06 Jul 2026 14:07:17 +0000</pubDate>
      <link>https://dev.to/amedinat/your-llm-bill-is-a-ticking-time-bomb-heres-how-to-defuse-it-2foi</link>
      <guid>https://dev.to/amedinat/your-llm-bill-is-a-ticking-time-bomb-heres-how-to-defuse-it-2foi</guid>
      <description>&lt;p&gt;Everyone's rushing to bolt LLM features onto their products. A quick look at Upwork shows thousands of jobs for "LLM integration" and "AI automation". It's a gold rush. But very few are talking about the second-order effects. Specifically, the cost.&lt;/p&gt;

&lt;p&gt;It's not about the per-token price on a vendor's website. That's just the entry fee. The real cost—the one that blows up budgets—is far more insidious. We're all dangerously skipping the rigor on cost analysis, and it's going to bite us.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real TCO of an LLM Feature
&lt;/h3&gt;

&lt;p&gt;I saw a team blow through $20k in a single weekend. The culprit? A runaway agent caught in a retry loop. Their generic cloud budget alerts didn't even notice until Monday morning.&lt;/p&gt;

&lt;p&gt;This is the new reality. Traditional tools like AWS Cost Explorer can't see inside an API call. They see you made a request to OpenAI; they have no idea if it was for a $0.01 summary task or a $100 recursive agent run. This is the "FinOps for AI" gap.&lt;/p&gt;

&lt;p&gt;The Total Cost of Ownership (TCO) for your shiny AI feature isn't just &lt;code&gt;(prompt_tokens * input_cost) + (completion_tokens * output_cost)&lt;/code&gt;. It's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Engineering Time:&lt;/strong&gt; Hours spent debugging prompts, optimizing models, and firefighting when costs spike.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Scaling Risk:&lt;/strong&gt; A feature that costs $10/day with 100 users will bankrupt you at 10,000 users if it scales linearly.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cost of Errors:&lt;/strong&gt; Bad or inconsistent outputs burn API credits and, more importantly, user trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Actually Do Cost Control
&lt;/h3&gt;

&lt;p&gt;If you're building with LLMs and don't have a dashboard showing you cost-per-user or cost-per-feature, you're flying blind.&lt;/p&gt;

&lt;p&gt;The first step is instrumentation. Every single API call needs to be tagged with metadata. Who is the user? What feature are they using? What's the conversation ID?&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;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Don't&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;just&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;API&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;openai.chat.completions.create(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;own&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;context&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;trackCost(&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;userId:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;featureId:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"summarize_document"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;tenantId:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"acme_corp"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;openai.chat.completions.create(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without this, you can't attribute costs. You can't tell which customers are profitable, which features are too expensive, or when a single user starts abusing the system.&lt;/p&gt;

&lt;p&gt;You need a dedicated tool for this. I've been building LLMeter (llmeter.org) to solve this problem for my own projects. It's an open-source dashboard that monitors costs across providers like OpenAI, Anthropic, and Mistral. It gives you that crucial per-user and per-feature breakdown. Since it's AGPL, you can just self-host it and avoid vendor lock-in.&lt;/p&gt;

&lt;p&gt;Whatever you use, the principle is the same: stop guessing. Start measuring. Your budget depends on it.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>How to Track Per-User OpenAI Costs in Your Next.js App</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Tue, 30 Jun 2026 16:01:35 +0000</pubDate>
      <link>https://dev.to/amedinat/how-to-track-per-user-openai-costs-in-your-nextjs-app-291c</link>
      <guid>https://dev.to/amedinat/how-to-track-per-user-openai-costs-in-your-nextjs-app-291c</guid>
      <description>&lt;p&gt;So you've integrated the OpenAI API into your Next.js app. Your users love it. But then you get the bill, and you have no idea who's costing you what. A single "power user" could be driving 90% of your costs, and you'd be flying blind.&lt;/p&gt;

&lt;p&gt;Let's fix that. Tracking per-user costs isn't just a nice-to-have, it's essential for any application that exposes an LLM to end-users.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem: The Un-instrumented API Call
&lt;/h3&gt;

&lt;p&gt;Your code might look something like this. You have an API route in Next.js that calls OpenAI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/api/generate.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&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;openai&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;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&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;OPENAI_API_KEY&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;completion&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;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Say this is a test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&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="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&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 works, but it's a black box. You know a call was made, but you don't know &lt;em&gt;who&lt;/em&gt; made it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Attribute Every Call
&lt;/h3&gt;

&lt;p&gt;To fix this, you need to attribute every single API call to a user. This means passing a unique user identifier with every request.&lt;/p&gt;

&lt;p&gt;First, protect your API route to make sure you have a user session. Then, wrap your OpenAI calls in a helper function that logs the cost.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/openai.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCostForModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saveUsageToDatabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./billing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Fictional helpers&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openai&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;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&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;OPENAI_API_KEY&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createChatCompletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;completion&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;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&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;promptTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prompt_tokens&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&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;completionTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;completion_tokens&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Calculate cost based on model (you have to maintain these prices)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCostForModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promptTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completionTokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Save to your database&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;saveUsageToDatabase&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;promptTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;completionTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;cost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;completion&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;You'd need a database table to store this, maybe in Supabase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;llm_usage&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;bigserial&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="k"&gt;zone&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;prompt_tokens&lt;/span&gt; &lt;span class="nb"&gt;integer&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;completion_tokens&lt;/span&gt; &lt;span class="nb"&gt;integer&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cost&lt;/span&gt; &lt;span class="nb"&gt;numeric&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="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Shortcut: Don't Build It Yourself
&lt;/h3&gt;

&lt;p&gt;As you can see, this is a lot of boilerplate. You need to maintain pricing for different models, build a robust logging system, and create a dashboard to view the data.&lt;/p&gt;

&lt;p&gt;This is a problem I ran into, so I built LLMeter (llmeter.org). It's an open-source, AGPL-licensed dashboard you can self-host. It gives you a simple SDK to wrap your LLM calls and automatically handles the cost calculation, logging, and dashboarding for multiple providers (OpenAI, Anthropic, Mistral, etc.).&lt;/p&gt;

&lt;p&gt;It turns the code above into something much simpler and gives you a production-ready dashboard out of the box.&lt;/p&gt;

&lt;p&gt;Whether you build it yourself or use a tool, the takeaway is the same: if you're not tracking LLM costs on a per-user basis, you're driving with your eyes closed. Don't wait for the surprise bill to learn that lesson.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
    <item>
      <title>How to Stop One Customer From Blowing Up Your Entire LLM Budget</title>
      <dc:creator>John Medina</dc:creator>
      <pubDate>Mon, 22 Jun 2026 14:06:46 +0000</pubDate>
      <link>https://dev.to/amedinat/how-to-stop-one-customer-from-blowing-up-your-entire-llm-budget-4mac</link>
      <guid>https://dev.to/amedinat/how-to-stop-one-customer-from-blowing-up-your-entire-llm-budget-4mac</guid>
      <description>&lt;p&gt;So your SaaS is finally getting some traction. Congrats. Then you check your OpenAI bill and realize one power user just cost you $500 overnight running reports. Now what?&lt;/p&gt;

&lt;p&gt;This isn't a rare problem. If you're building any multi-tenant AI app, your biggest financial risk is a single user with a runaway script or an unpredictable use case. Standard API rate limits are too crude—they punish all users and can kill legitimate usage. Manually watching your dashboard doesn't scale past your first few customers.&lt;/p&gt;

&lt;p&gt;You need a way to track costs &lt;em&gt;per user&lt;/em&gt; and enforce budgets automatically.&lt;/p&gt;

&lt;p&gt;Most people start by trying to build this logic in-house. You can add a &lt;code&gt;user_id&lt;/code&gt; to your API calls and log the token counts to your own database. Then you run a cron job to aggregate costs and check against a &lt;code&gt;budget&lt;/code&gt; column in your &lt;code&gt;users&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;It works, until it doesn't.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Provider differences:&lt;/strong&gt; The way you calculate costs for OpenAI is different from Anthropic, and different again for OpenRouter. Your logic gets complex fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timing issues:&lt;/strong&gt; Cron jobs aren't real-time. By the time your job runs, a user could have already gone 2x over their budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance:&lt;/strong&gt; It's another piece of infrastructure you have to build, test, and maintain. That's time you're not spending on your core product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tbh, I got tired of rebuilding this for every project.&lt;/p&gt;

&lt;p&gt;So I built a simple, open-source tool to handle it: &lt;a href="https://llmeter.org" rel="noopener noreferrer"&gt;LLMeter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's a dashboard that sits on top of your existing LLM providers (OpenAI, Anthropic, etc.). You tell it which user made which API call, and it handles the rest.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracks costs per-user, in real-time.&lt;/li&gt;
&lt;li&gt;Lets you set a budget for each user.&lt;/li&gt;
&lt;li&gt;Sends you a webhook or email when a user hits 50%, 90%, or 100% of their budget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can then use that webhook to programmatically disable that user's access, switch them to a slower model, or just notify them. No more surprise bills.&lt;/p&gt;

&lt;p&gt;It's not a proxy, so it doesn't add latency. It's just a simple, open-source dashboard you can self-host or use the managed version. Fwiw, it solved my own problem. Maybe it'll solve yours too.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>opensource</category>
      <category>ai</category>
      <category>costtracking</category>
    </item>
  </channel>
</rss>
