BlogMetering

Tokens, credits, or requests: choosing the unit you meter (and price)

The pricing doc has three columns: $9, $19, $49. The prices took twenty minutes. The row above them - what a user actually gets for the money - has been blank for a week. That blank row is the real decision.

The decision that outlives your pricing page

The pricing doc has three columns: $9, $19, and $49. The numbers took twenty minutes. The row above them - what a user actually gets for the money - has been blank for a week, because nobody can decide whether the plan says 200 generations, 2 million tokens, or 500 credits. Here is why that row deserves more sweat than the prices: you will change the prices five times in the next two years and almost nobody will notice. The unit is different. It gets baked into your events schema, your usage bar, your upgrade nudges ("you have 12 generations left"), your support macros, and - hardest to undo - your customers’ mental model of what your product costs to use. Repricing is an edit. Re-uniting is a migration plus a re-education campaign for every existing user. Spend the hour now.

Three properties, and no unit gets all of them

Every candidate unit can be scored on three axes. Cost-accuracy: does the unit track your provider bill, so that a user consuming more units actually costs you proportionally more? User-legibility: can a customer predict, before clicking the button, what an action will cost them - and explain their plan to a colleague without opening a calculator? Gaming-resistance: can a determined user extract 10x the intended value while staying inside the unit’s letter of the law? No unit wins all three. Requests are legible and inaccurate. Tokens are accurate and illegible. Credits buy back legibility by making you the central banker of a tiny economy. Pricing design for AI products is not finding the unit without a weakness - it is deciding which weakness your product can afford, then building a guardrail against the one you picked.

Requests: the unit a user can count on their fingers

A request - one generation, one summary, one render - is maximally legible. "100 generations a month" requires no explanation, fits on a pricing card, and can be repeated verbatim in a Slack recommendation. That legibility is why it converts, and it is also where the accuracy goes to die: for any LLM-backed action, one "request" can be 200 tokens or 200,000. A user who pastes a tweet and a user who pastes a 300-page contract each consume one unit of their allowance while differing in cost to you by three orders of magnitude. And the spread is not random - it is adversarial, because the moment users learn that requests are the scarce resource, they stuff each one: longer prompts, batched questions, "also do these nine other things" appended to every message. Requests are still the right call when your actions have naturally bounded cost - a fixed-size image, a summary with a hard output cap, a 15-second video clip - or when UX simplicity is itself the product. Most consumer AI apps should start here, with eyes open.

Tokens and raw units: the unit your provider bills you in

Metering tokens (or seconds of video, or pixels rendered) gives you perfect cost-accuracy by definition - it is the unit on your provider invoice, so your margin per user is arithmetic instead of a distribution you pray over. Gaming-resistance is equally strong: there is no stuffing attack against a unit that measures the stuffing. What you give up is legibility, completely. Nobody outside your engineering team knows what 50,000 tokens buys them; users cannot predict whether the next click costs 400 tokens or 40,000, so the usage bar becomes a slot machine and your support inbox fills with screenshots of a meter the customer does not understand. Raw units are the right choice in exactly two situations: you sell to developers or API customers who already think in tokens, or you run a thin-margin B2B product where cost tracking is the point and your buyer reads the meter like an electricity bill. Selling raw tokens to consumers is how you get one-star reviews that say the pricing is confusing - because it is.

Credits: legibility you have to govern

Credits are the configurable middle. You define an exchange rate per action - one standard image costs 5 credits, a thousand tokens of chat costs 1, a second of video costs 20 - and suddenly a heterogeneous product has one number on the pricing page again. The user regains predictability (the button says what it costs before they click), and you regain cost-correlation, because expensive actions can simply cost more credits. The price you pay is that you now own a small economy. Somebody has to set the rates, defend them when a user notices that video is "overpriced" relative to images, and rebalance them when your provider cuts inference prices by 40% - which triggers the inevitable "why did the credit cost of X change" email thread, the closest thing SaaS has to a central bank press conference. Credits are worth that overhead when your actions are genuinely heterogeneous - text plus images plus video in one product - which describes almost every AI app eventually, even the ones that launched with a single model and a single button.

The hybrid most real apps converge on

After enough support tickets, most products land on the same compromise: a legible unit on the pricing page, with a raw unit underneath as a guardrail. The plan says "100 generations a month" - that is what the user sees, counts, and repeats to colleagues. Invisibly, every generation also counts toward a token budget (or a monthly cents cap), sized so that normal usage never touches it but a stuffed mega-prompt does. One event, two limits: the visible count group increments by one, the hidden cost group increments by the real token usage carried in the event’s metadata. The user who sends ordinary prompts never learns the second limit exists; the user running a 100k-token context through every "generation" hits the budget wall instead of your margin. The trick is that this must be one tracked event matching two limit groups - not two tracking calls, not an if-statement at the call site - or the two meters drift and the guardrail becomes a second source of bugs.

Size the hidden guardrail from your own distribution: take the 99th-percentile cost per action, multiply by the plan’s action quota, and add headroom. Normal users should never see it; only the outlier should.
// One tracked event, two limit groups
await vevee.track(userId, 'image_generation', 1, {
  model: 'flux',
  tokens: 8400, // real usage from the provider response
});
// -> "monthly generations"  unit: count,  quota: 100      (on the pricing page)
// -> "generation budget"    unit: tokens, quota: 1500000  (invisible guardrail)
//
// canUse checks BOTH groups - the stuffed prompt is stopped
// by the budget even though the count says 41/100

The decision checklist

Compressed to a card you can pin next to the pricing doc - find your product’s row and start there.

  • One action type with bounded cost → requests. Take the legibility win; it is real.
  • Selling to developers or via API → tokens (or the raw provider unit). Your buyer already thinks in it.
  • Heterogeneous actions - text, image, video in one product → credits, and budget the ongoing rate-governance work honestly.
  • Variable-cost actions behind a consumer-friendly unit → hybrid: a visible count, a hidden token or cents guardrail.
  • Tiebreaker for everything above: pick the unit your customer can say out loud when recommending your plan to a colleague. If the sentence needs a footnote, the unit is wrong.

If you change your mind later

You probably will - launching on requests and migrating to credits at the first multi-model release is the most common pricing migration in AI products. Whether it is survivable depends entirely on what you logged, not on what you charged. If every event in your history carries a quantity and metadata - which model, how many tokens, what variant - then the old usage can be re-priced under the new unit: you can compute what every existing user would have consumed in credits, grandfather them onto an equivalent allowance, and show them a usage history that makes sense in the new currency. If all you stored was a counter - "this user did 73 things" - there is nothing to re-price, and the migration becomes a guess dressed up as an email announcement. The lesson costs nothing today: log rich events from day one, with real quantities and real metadata, even if your current unit ignores most of it. The unit on the pricing page is a view over the data. Make sure the data can support a different view.

Whatever you pick, the meter should not care

The unit decision should live in your plan configuration, not in your application code - which is exactly how Vevee models it: limit groups carry a unit of count, tokens, seconds, or cents, and one tracked event can count toward several groups at once, so the hybrid pattern above is configuration, not a rewrite. Pick the unit your customers can say out loud, log everything underneath it, and keep the option to change your mind.

See your own numbers in two minutes.Add the SDK and your users, costs and revenue fill in on the next request.
Join waitlist

Keep reading

ShareCopy a link to this post.

Set your first limit in about five minutes.

50k operations free every month. No card required.
Join waitlist