Guides / track llm cost typescript

How to track LLM cost in TypeScript

Culpa's TypeScript SDK reports calls to a Culpa server, and the default install binds to localhost only. A cloud-hosted app therefore has no route home, so its spend goes unattributed until a relay gives it a mailbox. Culpa, a local-first LLM cost, margin, and forecast ledger, traces every call it receives, and the question worth asking first is which of your calls can reach it.

Why this happens

Local-first is a privacy property and a reachability constraint at the same time. A server bound to localhost can't be reached from a function running on someone else's infrastructure, which describes most production TypeScript. The result is a ledger that looks healthy and describes your development machine. Development traffic is a rounding error against production, so the coverage number is far worse than it feels, and nothing about the ledger itself signals that it's reading a sliver.

What this usually looks like

  • Your ledger has data and your production spend is nowhere in it.
  • Captured traffic follows your working hours rather than your customers'.
  • The features you see are the ones you've been developing, not the ones customers use.
  • Captured totals are orders of magnitude below the invoice rather than a few percent below.

Free, no card, no account

Run the free Cost Leak Scan

It shows your most expensive conversation before you install anything.

Run a free scan

Mistakes that cost the most

MistakeWhy it hurtsDo instead
Reading a populated ledger as a covered one.Development traffic populates a dashboard convincingly while representing almost no spend.Divide captured spend by the invoice on day one. Coverage is the first number to establish.
Assuming a cloud function can reach a local server.It can't, and the failure is silent because capture fails open by design.Give cloud workloads a relay, which is a reachable mailbox they can post to.
Confusing capture with reach.You can instrument perfectly and still record nothing if the reports have nowhere to land.Treat them as two checks. Is the call instrumented, and can the report arrive?

Run this check tonight

  1. Divide captured spend by your provider invoice. That single ratio is your coverage.
  2. Check whether the captured traffic pattern matches your customers' hours or your own.
  3. List where your code actually runs, and mark which of those can reach your Culpa server.
  4. Confirm whether a relay is armed for anything running outside your machine.
  5. Re-check coverage after arming it, and expect the number to move a long way.

A ledger that describes a laptop

Illustrative example

A product running 2 million calls a month in the cloud and 40,000 on a developer machine, on Claude Haiku 4.5 at real rates of $0.001 per 1k input and $0.005 output. Each call sends 2,000 input tokens and returns 300. Volumes are modelled.

Per call: (2 x $0.001) + (0.3 x $0.005) = $0.002 + $0.0015 = $0.0035
Cloud spend: 2,000,000 x $0.0035 = $7,000 a month
Development spend: 40,000 x $0.0035 = $140 a month
Without a relay the ledger holds $140 of a $7,140 bill
Coverage is 2%, and the dashboard looks populated the whole time

Two percent coverage on a dashboard that reads as normal. The failure mode of local-first capture isn't an error message, it's a plausible-looking ledger about the wrong machine.

Every number, with its confidence and source

FigureWhat it meansConfidenceSource
$140 to $7,140modelled monthly spend a local-only ledger captures against the full billestimatedBoth endpoints from the teardown arithmetic at real Claude Haiku 4.5 rates from the price book, effective 2026-07-02. A range because call volumes are modelled.
2%modelled capture coverage for a cloud-hosted product with no relay armedcalculated$140 divided by $7,140, from the teardown arithmetic.

What a generic answer can’t know

Coverage is the ratio between what your ledger holds and what you were billed, and no provider can compute it because it has never seen your ledger. Establishing it takes both numbers in one place. Culpa holds its half on your infrastructure, keeps your prompts and responses there, and counts the calls to run your plan.

Questions founders ask next

Can a Vercel or Lambda function report to a local Culpa?

Not directly, because the default install binds to localhost and a cloud function has no route to it. A relay gives those workloads a reachable mailbox to post to, which the local install then pulls from.

Is this the same thing as the Vercel AI SDK adapter?

No, and the two get confused because both mention Vercel. The adapter is about capturing a call. The relay is about the report reaching you when your code runs somewhere else. A cloud app usually needs both.

How do I know my coverage is bad?

Divide captured spend by the provider invoice for the same period. Anything far below one means calls are being made that never reach your ledger, and a populated dashboard isn't evidence against that.

On your infrastructure

Culpa runs on your infrastructure. Your prompts and responses never leave it. Culpa counts calls to run your plan, and it fails open, so if it ever breaks your app keeps running.


How Culpa works

Find the culprit. Not just the total.

Your dashboard shows what you spent. It stops short of who spent it. Culpa shows the conversation, the user and the feature behind it.

Your prompts stay local.

Culpa runs on your own infrastructure. What you send to a model reaches us at no point.

Every dollar has a name.

Follow any charge to the conversation, the user, the feature and the customer behind it.

See the bill before it lands.

Cost your next feature before you ship it. You get the likely bill and the worst case, at best, median, p90 and p99.

Three steps to your first answer.

1

Change one base URL.

Or drop in the Python or TypeScript library.

2

Find your most expensive conversation.

In the first session, not the first week.

3

Cost your next feature before you ship it.

Base URLhttp://localhost:4545/v1Your traffic keeps flowing if Culpa ever stops.

Why the bill went up

Example dashboard

Calls traced

418,209

across 3 projects

Spend this week

$378.41

+ $182 vs last week

Failed calls

312

74% retried, and you paid for all of them

+ $182 this week traced to one culprit

Spend over 14 days

$0$20$40$60$8024262830020406
user_384report_generatorconv_91fprompt_v1894,220 tokens3 retries$6.81

Most expensive users

user_384$38.42
user_119$21.07
user_562$14.90
user_204$8.30
user_871$5.10

Next week forecast

Best$180
Median$240
p90$310
p99$395

Graded against reality. Accuracy shown as results land.

Free, no card, no account

Run the free Cost Leak Scan

It shows your most expensive conversation before you install anything.

Run a free scan

Keep reading


Sources: Anthropic pricing. Last reviewed 2026-08-02. Plain text version.