The price per million tokens does not tell you what one user costs. One action can trigger several calls, read a long history and retry after an error. That complete flow is what you need to count before selling an AI feature.

Prices move quickly. OpenAI, for example, announced a Sol price adjustment on 21 August 2026. Rather than freeze a comparison that ages quickly, I prefer to keep rates separate from the calculation and date them when preparing a budget.

Start with the usage returned by the API

Add up every call belonging to a task. Separate regular input, input actually billed at cached rates and output. Do not assume a repeated prompt gets a cache discount. Use the provider’s usage counters and billing categories, including reasoning.

The calculation below takes an input total that includes cached tokens. It subtracts them before applying the regular rate to avoid counting them twice. Rates use the same currency, per million tokens.

token-cost.ts
type Usage = {
  input: number;
  cachedInput: number;
  output: number;
};

type Rates = {
  input: number;
  cachedInput: number;
  output: number;
};

export function tokenCost(usage: Usage, rates: Rates) {
  const values = [...Object.values(usage), ...Object.values(rates)];
  if (values.some((n) => !Number.isFinite(n) || n < 0)) {
    throw new Error("Usage and rates must be finite and non-negative");
  }
  if (usage.cachedInput > usage.input) {
    throw new Error("Cached input exceeds total input");
  }

  return (
    (usage.input - usage.cachedInput) * rates.input +
    usage.cachedInput * rates.cachedInput +
    usage.output * rates.output
  ) / 1_000_000;
}
Token estimate only, not the full invoice

Bring the calculation back to a useful action

With fictional rates of 2 for input, 0.5 for cached input and 8 for output, a call with 10,000 input tokens including 4,000 cached tokens, followed by 1,000 output tokens, costs 0.022 currency units. One thousand identical calls cost 22. These are not the rates of any specific model.

If one action needs three calls, that amount triples before paid tools are included. Add web search, storage, the VPS and billed retries separately. To compare two models, also look at successfully completed actions, not just responses received.

Set limits before the first sign-ups

Set per-user quotas, a maximum request size and a concurrency limit. A budget displayed in a dashboard may only be an alert. Check what actually blocks new requests, both at the provider and on your server.

I would keep a task identifier, model, usage and estimated cost to understand discrepancies. Tracking spending does not require storing every complete conversation. Reconcile the estimate with the invoice, especially when enabling new tools.