<?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: Roy Tong</title>
    <description>The latest articles on DEV Community by Roy Tong (@roytong).</description>
    <link>https://dev.to/roytong</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%2F4118697%2F14d08eb4-2784-4071-beaf-5f510e5e6d2e.png</url>
      <title>DEV Community: Roy Tong</title>
      <link>https://dev.to/roytong</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roytong"/>
    <language>en</language>
    <item>
      <title>We audited 110 AI usage tools. Here is where the numbers go wrong.</title>
      <dc:creator>Roy Tong</dc:creator>
      <pubDate>Tue, 22 Sep 2026 23:12:53 +0000</pubDate>
      <link>https://dev.to/roytong/we-audited-110-ai-usage-tools-here-is-where-the-numbers-go-wrong-5d8h</link>
      <guid>https://dev.to/roytong/we-audited-110-ai-usage-tools-here-is-where-the-numbers-go-wrong-5d8h</guid>
      <description>&lt;p&gt;AI products are moving from flat subscriptions to usage-based and outcome-based billing: per-resolution support agents, premium request quotas, per-token gateway billing. Every one of those numbers is produced by a meter, and the meter is usually the vendor's own. We spent the last month auditing the open-source side of that world — 110 tools that count tokens, track costs, or enforce budgets — and this post is the field report.&lt;/p&gt;

&lt;p&gt;The short version: &lt;strong&gt;45+ verified bugs, five recurring families, 23 fixes already merged upstream&lt;/strong&gt; (including langfuse at 34k stars and codeburn at 11k). An independent auditor reproduced our entire conformance suite and confirmed one cache-accounting path that under-reports usage by roughly 99%. Every claim below links to a reproducible check.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five bug families
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Stale pricing tables.&lt;/strong&gt; The most common real bug, and the most boring: pricing tables that lack the current generation of models. In one batch of seven tools, five shipped outdated or missing rate rows. The tool computes confidently from numbers that stopped being true months ago — and every downstream total inherits the error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Provider-wrong cache multipliers.&lt;/strong&gt; Cache reads and writes are billed at different multipliers per provider. A common shortcut hardcodes one provider's ratios and applies them to everyone. We found a tool applying Anthropic's cache-read discount to OpenAI models, underestimating cache reads by 5x. The billing math is wrong in a way that looks plausible on every individual line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Retry double-counting in stream aggregation.&lt;/strong&gt; When a streaming request is retried byte-identical, some aggregators count both attempts. In one public corpus of 604 re-emitted events — 46% of the corpus — the bytes were identical, and naive aggregation doubled them. Conversely, tools that deduplicate too aggressively miss genuine retried work. Both directions lose money for someone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Absent treated as zero.&lt;/strong&gt; When a usage field is missing, &lt;code&gt;or 0&lt;/code&gt; turns "unknown" into "free". It reads like defensive coding and behaves like a discount nobody authorized. The fix is semantic, not syntactic: absent must stay absent, and rollups must be allowed to say UNPROVABLE instead of zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Window boundary errors.&lt;/strong&gt; Quota windows anchored to wall-clock time with fixtures pinned to absolute dates — the tool passes tests for 30 days and then fails everywhere at once. We know this one intimately because our own CI did it to us.&lt;/p&gt;

&lt;h2&gt;
  
  
  An independent reproduction
&lt;/h2&gt;

&lt;p&gt;The part we are proudest of is not our numbers — it is that an external auditor, working separately, reproduced our full conformance suite (236 checks) and then contributed his own quantified audit of a commercial provider's cache accounting: four code paths failing, usage under-reported by 98.9% and 95.1% on the affected paths, pinned to an exact commit. That report is now in our evidence tree with named credit. A third party spending real effort to check your work is worth more than any testimonial.&lt;/p&gt;

&lt;h2&gt;
  
  
  What merged upstream
&lt;/h2&gt;

&lt;p&gt;23 fixes across the ecosystem carry the audit's fingerprints — pricing table updates, cache multipliers corrected per provider, retry-collapse guards with regression fixtures, absent-vs-zero semantics made explicit. None of these were adversarial finds. Every one started as a thread where the maintainer was already discussing the problem, which is the only place we work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What vendors should publish
&lt;/h2&gt;

&lt;p&gt;We checked 20 commercial vendors for one thing: a published process for what happens when the meter is wrong — a dispute path, a correction policy, anything. None had one. When the vendor runs the meter, grades its own homework, and publishes no correction process, "trust us" is the whole control framework. Two minimum standards would change that: a named dispute path, and machine-checkable billing disclosures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify your own bill in ten minutes
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/roy-tong/AgentMeasure" rel="noopener noreferrer"&gt;conformance pack&lt;/a&gt; is open source (MIT). Export your usage data, run the checker locally — nothing leaves your machine — and it separates logical operations from physical attempts, cache reads from cache writes, and absent from zero, with every verdict traceable to a named rule. If a number on your invoice survives an independent recount, you can defend it. If it doesn't, now you have the receipt.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The full audit report with per-tool findings: &lt;a href="https://github.com/roy-tong/AgentMeasure/blob/main/campaigns/audit-report-2026-09.md" rel="noopener noreferrer"&gt;campaigns/audit-report-2026-09.md&lt;/a&gt;. The settlement spec behind the checker: &lt;a href="https://github.com/roy-tong/AgentMeasure/blob/main/standard/SETTLEMENT.md" rel="noopener noreferrer"&gt;AMS-1&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>opensource</category>
      <category>observability</category>
    </item>
    <item>
      <title>I audited 110 AI usage/cost tools and filed 45+ verified billing bugs. Here's what they get wrong.</title>
      <dc:creator>Roy Tong</dc:creator>
      <pubDate>Thu, 10 Sep 2026 06:47:09 +0000</pubDate>
      <link>https://dev.to/roytong/i-audited-110-ai-usagecost-tools-and-filed-45-verified-billing-bugs-heres-what-they-get-wrong-38m3</link>
      <guid>https://dev.to/roytong/i-audited-110-ai-usagecost-tools-and-filed-45-verified-billing-bugs-heres-what-they-get-wrong-38m3</guid>
      <description>&lt;h1&gt;
  
  
  I audited 110 AI usage/cost tools and filed 45+ verified billing bugs
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; If a tool tells you what your AI coding agents cost, there is a real chance it is wrong in a systematic direction. I audited ~110 repositories across the Claude Code / Codex / gateway / eval / observability ecosystems and filed 65+ evidence-backed findings; &lt;strong&gt;10 have already been merged or accepted by maintainers&lt;/strong&gt;, several with public credit. The majority of audited tools passed clean — including some of the largest (promptfoo, Portkey's model data, TokenTracker) — so this is not "everything is broken"; it is five specific, findable bug classes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/roy-tong/AgentMeasure/blob/main/campaigns/audit-report-2026-09.md" rel="noopener noreferrer"&gt;Full report with every finding linked&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The five classes that keep appearing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. One assistant message ≠ one line (10 confirmed tools)
&lt;/h3&gt;

&lt;p&gt;Claude Code writes &lt;strong&gt;one JSONL line per content block&lt;/strong&gt; of an assistant message, and every line carries the same &lt;code&gt;message.id&lt;/code&gt; and the same &lt;code&gt;message.usage&lt;/code&gt;. Sum per line and a message with text + two tool calls is billed 3×. Real overcounts we measured: 2×–5×.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhangferry/tokendash/pull/37" rel="noopener noreferrer"&gt;tokendash #37&lt;/a&gt; (49★, merged): 3-block message → 3× tokens and cost&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Genuifx/ccem/issues/12" rel="noopener noreferrer"&gt;ccem #12&lt;/a&gt;: same shape, first-wins variant undercounts instead&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ipeterpetrus/samewrite/issues/1" rel="noopener noreferrer"&gt;samewrite #1&lt;/a&gt;: a &lt;em&gt;research project's&lt;/em&gt; headline numbers rested on it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Re-emitted events (5 tools)
&lt;/h3&gt;

&lt;p&gt;Codex re-emits &lt;code&gt;token_count&lt;/code&gt; events with identical totals after compaction, settings changes, and rate-limit refreshes. Naive per-event accumulation double-counts. Measured on real corpora: +0.5% to +15% per session file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/extrei/token-vision/issues/1" rel="noopener noreferrer"&gt;token-vision #1&lt;/a&gt;: one real rollout, +14.97%&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/stealthsrc/tokenscope/pull/6" rel="noopener noreferrer"&gt;tokenscope #6&lt;/a&gt; (merged), &lt;a href="https://github.com/avihut/coding-agent-usage-tracker/pull/1" rel="noopener noreferrer"&gt;coding-agent-usage-tracker #1&lt;/a&gt; (merged)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Cache-pricing semantics (9 tools)
&lt;/h3&gt;

&lt;p&gt;Anthropic's &lt;code&gt;input_tokens&lt;/code&gt; &lt;strong&gt;excludes&lt;/strong&gt; cache tokens; OpenAI's includes them. 5-minute cache writes cost 1.25× input, 1-hour writes 2×, reads 0.1×. Tools that apply one convention to both providers clamp input to $0, double-charge cache, or price 1h writes as 1.25×.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jarrodwatts/claude-hud/pull/758" rel="noopener noreferrer"&gt;claude-hud #758&lt;/a&gt; (27.9k★): 1h writes at 1.25× — 37.5% understated on that component&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/modelbus/one-api-pro/issues/13" rel="noopener noreferrer"&gt;one-api-pro #13&lt;/a&gt;: streaming &lt;code&gt;+=&lt;/code&gt; double-counts input (+50.7% with no cache) &lt;strong&gt;and&lt;/strong&gt; the billing formula re-subtracts cache&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Price-table drift (7 tools, including the source)
&lt;/h3&gt;

&lt;p&gt;Embedded price snapshots diverge from published rates by 1.2×–5× — including in vendored copies of &lt;strong&gt;LiteLLM's price file&lt;/strong&gt;, the industry's source of record (&lt;a href="https://github.com/BerriAI/litellm/issues/40360" rel="noopener noreferrer"&gt;litellm #40360&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Resume/fork history loss (4 tools)
&lt;/h3&gt;

&lt;p&gt;Codex resume writes a new rollout file whose &lt;code&gt;session_meta.id&lt;/code&gt; is the &lt;em&gt;original&lt;/em&gt; session id. Stores that replace-per-session wipe everything before the resume; fork re-plays the parent prefix and double-counts it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Kud0o/ai-usage-inspector/issues/1" rel="noopener noreferrer"&gt;ai-usage-inspector #1&lt;/a&gt;: 86% of a session's tokens vanish (real pair measured)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ra3orblade/swarm/issues/145" rel="noopener noreferrer"&gt;swarm #145&lt;/a&gt; → &lt;a href="https://github.com/ra3orblade/swarm/pull/146" rel="noopener noreferrer"&gt;fixed in #146&lt;/a&gt; with maintainer credit: &lt;em&gt;"reported and diagnosed by @roy-tong, who also supplied the patch this follows"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why you should care even if you don't use these tools
&lt;/h2&gt;

&lt;p&gt;Your billing dashboards, your FinOps exports, and every "how much did this agent cost" number downstream inherit these errors. The bugs are findable with &lt;strong&gt;synthetic fixtures in minutes&lt;/strong&gt; — most tools' own tests never model these shapes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit your own tool in 10 minutes
&lt;/h2&gt;

&lt;p&gt;The fixture corpus is open data — plain JSONL + expected totals, no runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 https://github.com/roy-tong/AgentMeasure
python3 conformance/pack/agentmeasure selftest   &lt;span class="c"&gt;# see the expected-totals style&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full method and per-class pointers: &lt;a href="https://github.com/roy-tong/AgentMeasure/blob/main/campaigns/tool-authors.md" rel="noopener noreferrer"&gt;tool-authors.md&lt;/a&gt;.&lt;br&gt;
Full case list: &lt;a href="https://github.com/roy-tong/AgentMeasure/blob/main/campaigns/measurement-casebook.md" rel="noopener noreferrer"&gt;measurement-casebook.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honesty notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Counts are of &lt;em&gt;filings with pinned evidence&lt;/em&gt;, as of 2026-09-10; merges happen as maintainers get to them (10 accepted so far).&lt;/li&gt;
&lt;li&gt;Most audited repos passed. We name the clean ones because that matters.&lt;/li&gt;
&lt;li&gt;All reproductions are synthetic; no private logs anywhere.&lt;/li&gt;
&lt;li&gt;This audit was performed with the methods and fixtures of &lt;a href="https://github.com/roy-tong/AgentMeasure" rel="noopener noreferrer"&gt;AgentMeasure&lt;/a&gt; — that is the demo. No audited project endorses it.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codex</category>
    </item>
  </channel>
</rss>
