AI Unit Economics: How to Actually Attribute LLM Cost to a Customer or Feature

Token-level cost attribution has to happen at the point of the LLM call — tag customer, feature, and model at call time, not reconstructed later from a provider invoice. Structure it like a ledger, not a spreadsheet, and normalize across providers early, because most products end up using more than one model within a year.
A provider invoice tells you the total spend for the month. It does not tell you whether that spend came from one enterprise customer running a heavy workflow or from ten thousand free-tier users hitting a feature that should be rate-limited. Without attribution, "AI costs are up" is a fact with no next action attached to it.
The question finance actually asks
Not "what did we spend on OpenAI" but "what does it cost us, per customer, to run feature X" — because that number determines pricing, gross margin, and which features are subsidizing which customers. Answering it requires cost data at the transaction level, joined to customer and feature identifiers, not just a monthly total.
Why provider dashboards don't answer it
Provider billing dashboards are organized by API key and model, not by your product's concept of a customer or a feature. Unless every distinct customer or feature has its own API key (which does not scale), the provider's view of spend has no way to map back to your business logic.
Attribution has to happen at the call, not after
The only reliable pattern is to tag cost at the moment of the LLM call — wrap every request with the customer ID, feature name, and model, and log token counts and cost alongside that context immediately. Trying to reconstruct this after the fact from logs or invoices is lossy and usually wrong.
def call_llm(prompt, *, customer_id, feature, model):
response = client.messages.create(model=model, messages=prompt)
log_cost_event(
customer_id=customer_id,
feature=feature,
model=model,
input_tokens=response.usage.input_tokens,
output_tokens=response.usage.output_tokens,
cost=compute_cost(response.usage, model),
)
return responseTreat it like accounting, because it is accounting
Cost events at the scale of a real product are financial records, and they benefit from being modeled like one — a structured ledger with accounts (by customer, by feature, by provider), not a wide analytics table that gets reshaped every time someone asks a new question. A proper chart-of-accounts structure makes "cost by customer this month" and "cost by feature this quarter" the same kind of query, not two different ad-hoc scripts.
Multi-provider normalization is not optional
Almost every team ends up using more than one model provider within a year — a cheaper model for high-volume classification, a stronger one for the task that needs it, maybe a second provider for redundancy. Cost attribution that only works for one provider's pricing structure has to be rebuilt the day a second provider shows up. Normalize cost calculation behind a single interface from day one.
Retries and failures need their own cost line
A cost model that only tags successful calls misses a real and sometimes large source of spend: retries, timeouts, and failed calls that still got billed. A degraded provider triggering a retry storm doesn't just hurt reliability — it can spike cost per customer or per feature well past what the attribution model expects, and if failed/retried calls aren't tagged the same way successful ones are, that spike is invisible in the cost data until someone notices the invoice.
What this looks like as real infrastructure
This isn't a theoretical model — it's the same double-entry ledger approach we use for our own billing infrastructure internally: cost events as immutable, structured records with accounts (by customer, by feature, by provider), rather than a mutable spreadsheet reshaped every time someone asks a new question. Treating cost attribution as an accounting problem, with the same rigor as financial records, is what makes it hold up once more than one team is asking it questions.
For the retry-storm cost spike specifically, see the LLM cost curve nobody models.
Frequently asked questions
Should failed or retried LLM calls be included in cost attribution?
Yes — a failed or retried call is often still billed by the provider, and excluding it from attribution just means that cost shows up as an unexplained gap between the provider invoice and your internal cost model, usually discovered at the worst possible time.
How early should cost attribution be built, relative to launch?
Before the first customer-facing bill or margin conversation, ideally — retrofitting attribution onto months of un-tagged historical calls is lossy at best. Tagging customer, feature, and model at the call site from day one costs almost nothing to build in and is very expensive to reconstruct later.
The takeaway

Have a similar challenge?
Book a free 30-minute architecture call and we'll tell you honestly whether and how we can help.
Book Free Discovery Call →