Skip to content

Cost and FinOpsGuide

Cost per successful task: the LLM metric that matters

A model with a lower list rate can cost more per finished piece of work if it fails more often. Cost per successful task puts every attempt, retry and fallback in the numerator and only the work that succeeded in the denominator.

By INFRO Editorial

Published

7 min read

Amber columns of different heights under a glowing trend line on a dark ground, representing cost per successful LLM task

In short

Cost per successful task is the total estimated provider cost of every attempt at a unit of work — first calls, retries, fallbacks, validation failures and tool steps — divided by the number of units that succeeded. It is the number to compare models, prompts and routes on, because cost per token and cost per call ignore how often the work has to be redone. Compute it by tagging every call with a workflow and a run id, summing cost per run, and joining the runs with a success signal your system already records.

Key takeaways

  • Cost per token and cost per call measure inputs. Cost per successful task measures what the business bought.
  • Put every attempt in the numerator — retries, fallbacks, failed validations, tool steps — and only successes in the denominator.
  • A lower list rate loses when it needs more attempts per task or succeeds less often; the arithmetic takes three numbers.
  • Define success with a check your system already runs, not with a model grading itself.
  • Report the unpriced share beside every figure, and use the median and p90 cost per run, not only the mean.

Model comparisons usually start with a price table: input rate, output rate, maybe a blended rate per million tokens. Those numbers are real and they matter, but they measure the wrong thing. Nobody's product sells tokens. It sells a resolved ticket, a correctly extracted invoice, a passing test, an accepted summary. What that unit costs depends as much on how often the model has to try again as on what each try costs.

Three levels of unit cost

The FinOps Foundation distinguishes resource-efficiency unit metrics, such as cost per token, from business unit metrics, such as cost per customer or cost per transaction, and describes unit economics as relating costs to the benefits received1. For LLM workloads there are three useful levels:

  • Cost per token — the provider's rate. Useful for forecasting, useless for comparing models that use different numbers of tokens for the same work.
  • Cost per call — tokens times rates for one request. Better, but it treats a call that produced garbage the same as one that produced the answer.
  • Cost per successful task — everything spent trying to complete a unit of work, divided by the units completed.

The last one is the only one that goes down when a model gets better at the job.

The formula

Cost per successful task
cost_per_successful_task = Σ cost of every call in every run  /  number of runs that succeeded

where a run is one attempt to complete one unit of work, and includes:
  first attempt + same-target retries + fallbacks to other targets
  + calls whose output failed validation + every tool-loop step

Two properties matter. Failed runs are in the numerator and not in the denominator, so a model that fails more often pays for it. And every call a run makes counts, including the ones your application threw away, because your provider billed them.

Not every failure is billed. Anthropic does not bill batch requests that errored, were canceled or expired2, and OpenAI does not charge for a flex request refused with 429 Resource Unavailable3. But an attempt that timed out on your side after the provider finished it, or an answer your schema validator rejected, was billed in full. The only reliable numerator is the sum of what each call was actually estimated to cost.

Why a lower rate can lose

Estimated provider cost, USD

  • Model A, per call$0.0020
  • Model B, per call$0.0060
  • Model A, per successful task2.6 calls a task, 55% succeed$0.0095
  • Model B, per successful task1.1 calls a task, 96% succeed$0.0069
Illustrative: cost per call against cost per successful task for the two models in the example above.
  • First attempt
  • Retries after failed validation
  • USD per run
  • Model A$0.0052
  • Model B$0.0066
Illustrative: where the cost of one run goes. Most of model A's run cost is retries after failed validation.

The general form is cost_per_call × calls_per_run / success_rate. It makes the break-even between two options easy to see: a model three times the price per call wins if it cuts calls per run and raises the success rate enough that the product of those two ratios exceeds three.

Defining success

The metric is only as honest as the success signal. Prefer signals your system already produces for reasons that have nothing to do with the model:

  • Deterministic checks: the output parsed, matched the schema, passed the unit tests, compiled.
  • Downstream acceptance: the user sent the drafted reply without rewriting it, the ticket closed without escalation, the extracted invoice posted without a correction.
  • Sampled human review, when the above do not exist, on a fixed random sample per week.

Avoid a model grading its own output as the only signal. Keep the definition fixed while comparing options; changing what counts as success halfway through a comparison changes the answer.

Instrumenting it

The instrumentation is two identifiers and one join.

  1. A workflow name on every call: the stable name of the work, such as invoice-extract.
  2. A run id on every call made for one unit of work, including retries and fallbacks.
  3. A success record keyed by the same run id, written by the part of your system that knows whether the work succeeded.
  1. 1

    Define success

    A check your system already runs: schema valid and accepted, ticket resolved, test passed.

  2. 2

    Tag every call

    One workflow name and one run id per task, on every model call it makes.

  3. 3

    Sum every attempt

    Retries, fallbacks, validation failures and tool steps all belong to the run.

  4. 4

    Divide by successes

    Total cost of all runs over the number of runs that succeeded.

The four steps to cost per successful task: define success, tag every call, sum every attempt per run, divide by successful runs.

The join itself is short. Here it runs against per-run costs from a gateway API and a success table from your own database:

cpst.py
import os
from decimal import Decimal

import requests

def run_costs(workflow: str, period: str) -> dict:
    resp = requests.get(
        "https://api.infro.io/v1/unit-economics",
        params={"by": "workflow", "period": period},
        headers={"Authorization": f"Bearer {os.environ['INFRO_API_KEY']}"},
        timeout=30,
    )
    resp.raise_for_status()
    for row in resp.json()["data"]:
        if row["group"] == workflow:
            return row
    raise LookupError(f"no runs for {workflow} in {period}")

def cost_per_successful_task(workflow: str, period: str, successful_runs: int) -> dict:
    row = run_costs(workflow, period)
    total = Decimal(row["estimated_cost"])
    return {
        "workflow": workflow,
        "runs": row["runs"],
        "successful_runs": successful_runs,
        "success_rate": successful_runs / row["runs"] if row["runs"] else None,
        "cost_per_successful_task": total / successful_runs if successful_runs else None,
        "unpriced_share": row["unpriced_share"],  # a partial figure must say so
    }

The total here covers every request tagged with the workflow, including requests without a run id; count only runs that carry one if your success table is keyed by run.

Reading the number

  • Look at the distribution, not only the mean. Median and p90 cost per run show whether a few runaway runs dominate. An agent with a low median and an expensive tail needs a step or spend limit, not a different model.
  • Report the unpriced share beside the figure. If some calls ran on a model with no known rate, the cost is a lower bound; say so rather than publishing it as whole.
  • Compare like with like. Same task mix, same period, same success definition. Seasonal changes in input length move cost per task without anything being better or worse.
  • Revisit when rates change. A provider price change, a new snapshot or a new negotiated rate changes the numerator. The success rate does not change with price; recompute the product.

Using it to choose

Cost per successful task turns model selection, prompt changes and routing into one comparable number, but only if every option is measured the same way.

  • Run options on the same sample. A fixed, labelled set of real inputs, large enough that a few percentage points of success rate are not noise. See evaluating LLMs on real workloads.
  • Include the fallback path. If a route falls back to a second model when the first fails, the route's cost per successful task includes both. Measure the route, not the models in isolation.
  • Price with the rates you pay. A negotiated rate on one provider can reverse a comparison made at list prices. Use your own rates where you have them.
  • Account for the failures you do not see. If failed runs go to a person, add that handling cost per failure to the comparison, separately from provider cost, so the two are not blended into one figure.
  • Recheck after changes. A new snapshot, prompt or effort setting changes both the numerator and the success rate. Re-run the sample before and after.

A useful habit is to publish the three inputs next to the result: cost per call, calls per run, success rate. When cost per successful task moves, the inputs say which lever moved it.

Cost per run in INFRO

INFRO records the cost dimensions; your application records success. Send metadata.workflow and metadata.trace_id on every call (or the X-INFRO-Workflow and X-INFRO-Trace-Id headers), and INFRO treats one (workflow, trace_id) pair as a run. Unit economics, on every plan, returns per group the requests, runs, total estimated cost, cost per request, and the median and p90 cost per run, with unpriced_requests and unpriced_share beside every row:

Cost per run by workflow, August
curl "https://api.infro.io/v1/unit-economics?by=workflow&period=2026-08" \
  -H "Authorization: Bearer $INFRO_API_KEY"

Requests without a trace id count toward cost and cost per request but not toward runs, median or p90. Retries your application sends are new requests with their own cost, and count toward the run when they carry the same trace id. Failover inside the gateway is recorded on the request that finally served, with each failed attempt listed; a charge your provider makes for an attempt that failed on INFRO's side, such as a timed-out call it still completed, is outside the estimate, as spend controls states. Group by=feature, end_user or cost_center for the same view along other dimensions. All figures are estimates of what your own providers bill you; INFRO platform fees are not included. INFRO sees request metadata, not answers, so it does not judge whether a run succeeded — that join stays yours.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

INFRO is in private early access. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.Unit Economics capability (opens in a new tab) — FinOps Foundation. Accessed Sep 29, 2026.
  2. 2.Batch processing (opens in a new tab) — Anthropic. Accessed Sep 29, 2026.
  3. 3.Flex processing (opens in a new tab) — OpenAI. Accessed Sep 29, 2026.

About this article

Written from the FinOps Foundation's Unit Economics capability, opened on 2026-09-29, and from the attribution and unit-economics documentation and implementation of the INFRO gateway, which the authors build. The two-model comparison is illustrative arithmetic, not a measurement of any model.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.