Cost and budgets
cairn treats cost as something you decide on before the money is spent, and check afterwards. Three mechanisms work together: a pricing step you can gate on, a budget that flow legs reserve against, and cost thresholds that belong to the environment.
Price it first
Section titled “Price it first”cairn does not guess a price for you. Pricing is a step in the pipeline, done by an operator that knows how:
| Operator | Prices |
|---|---|
cost/tokens | model calls, from a token count and the model’s price; it refuses to price a model it does not know instead of reporting $0 |
compute/estimate | a GPU run: hours, memory and dollars |
compute/quote | live GPU offers, next to cairn’s own estimate |
Because the price is an ordinary step output, a gate can read it.
Stop on the price: a data gate
Section titled “Stop on the price: a data gate”The public serving/batch-inference pipeline prices the job, then lets a
predicate decide whether it may start:
- id: estimate task: cost/tokens with: model: $input.model rows: $input.rows prompt_tokens: $input.est_prompt_tokens completion_tokens: $input.max_tokens sample_prompt: $input.sample_prompt
- gate: cost depends_on: [estimate] predicate: steps.estimate.usd <= input.max_cost_usdWhen the estimate is above max_cost_usd (5 dollars unless you pass another
value), the gate blocks and the pipeline stops before the batch leg runs. The
same rows input becomes the batch job’s hard row limit, so the job cannot
process more than the gate priced. A last spend leg prices the tokens the job
really used, so the record holds the measured cost, not the estimate.
Budgets on the pipeline
Section titled “Budgets on the pipeline”A pipeline declares its budget in governance:
governance: budget: {usd: 25} series: batch-inference approvers: platformbudget.usdis the pipeline’s spending cap. Every gate shows the person deciding how much the pipeline has spent so far against it.seriesnames a group of runs that share that cap. Before a flow leg starts its engine, it reserves the pipeline’sgovernance.estimated_usdagainst the series cap. The reservation is atomic (a lock per series on Postgres), so two legs cannot both take the last dollar.
When a reservation would go over the cap, the leg fails before it spends, with this message (values filled in):
series '<series>': this run's estimate $<estimate> would exceed the $<cap> cap($<spent> spent, $<held> reserved by in-flight runs). Raise the budget or start a new series.A finished leg settles its reservation. A failed or cancelled leg releases it. A retried attempt reserves again, because a retry is new spend.
Cost thresholds belong to the environment
Section titled “Cost thresholds belong to the environment”The cost/gate operator turns a GPU estimate into a pass, warn or fail
verdict. Its thresholds are set by the environment, not by the pipeline:
[profile.config."cost/gate".thresholds]max_usd = 40warn_usd = 25require_fit = true| Threshold | Default | Meaning |
|---|---|---|
max_usd | 0 (no cap) | an estimate above this fails |
warn_usd | 0 (off) | an estimate above this warns, without blocking |
require_fit | true | a run that will not fit the GPU’s memory fails |
These are governance settings: a pipeline or a run cannot loosen them. The
shipped profiles leave them at their defaults, so set them in your
deployment’s profile. The training/finetune pipeline is one that runs this
gate before a GPU is provisioned.
What a run cost
Section titled “What a run cost”Every run records its cost split into model calls, GPU and storage, plus a total. The pipeline page and Runs add them up per leg and per pipeline.
- Gates and approvals: the gates that read these numbers.
- Runs and the record: where the cost is kept.
- Pipeline catalog: the pipelines that price their work.