Documentation

Spending limits and cost guardrails

Put a ceiling on live AI spend at the project level or on individual workflow models. Watch usage on Overview and stop over-budget requests before they hit a provider.

Overview

Spending limits let you cap estimated USD spend on live AI traffic. In the console they show up as Spending limit (project-wide) and Cost guardrail (per workflow model).

You can set one, the other, or both:

  • Project spending limit — total priced spend across the project
  • Workflow spend cap — spend on a specific primary, backup 1, or backup 2 model

Each limit uses a UTC period (hourly, daily, weekly, or monthly). When spend hits the cap, new provider calls are blocked and the API returns a budget error.

Different from input guardrails: Input guardrails block unsafe content. Spending limits block requests when a budget threshold is reached.


How checks run

On a normal live request, ModelRiver evaluates limits in this order:

  1. Test mode — if the workflow is in test mode, all spending limits are skipped
  2. Cache hit — cached responses with price = 0 skip limits entirely
  3. Project cap — if configured and spend is at or above the cap, the request is blocked immediately (no failover)
  4. Workflow slot cap — if that model slot is over its cap, it is skipped and the next backup is tried

If the project cap is already reached, backups do not run — even when a workflow slot still shows budget left on Overview.

This applies across sync, async, streaming, playground (production workflows), and OpenAI-compatible routes.


What counts as spend

Project totals

Project spend sums successful request logs where:

  • status is success
  • price is greater than 0
  • primary_req_id is empty (top-level requests only — child failover rows are excluded)

Workflow slot totals

Workflow caps track spend for a specific workflow + provider + model pair. Here ModelRiver sums successful logs with a non-null price for that slot, including priced failover attempts on the same model.

Cache hits (price = 0) never add to either total and never trigger a budget check.


Budget periods

All periods use UTC boundaries:

PeriodResets at
hourlyTop of each UTC hour
dailyMidnight UTC
weeklyMonday 00:00 UTC
monthlyFirst day of the UTC month

Overview and budget error responses include period_start and reset_at when helpful.


Set a project spending limit

  1. Open the project and go to Settings (sidebar)
  2. In Spending limit, enter Maximum spend (USD) — amounts like $0.009 are supported (up to three decimal places)
  3. Pick Reset every (hourly, daily, weekly, or monthly)
  4. Save

Clear the amount and save to remove the limit. The amount must be greater than zero, and a period is required whenever a cap is set.


Set workflow spend caps

  1. Open Workflows and edit a production workflow
  2. On the primary, backup 1, or backup 2 step, open Cost guardrail
  3. Set Budget (USD) and Reset
  4. Save the workflow

Only slots with a provider and model selected can be capped.

When a capped slot is over budget, that model is skipped. ModelRiver moves on to the next backup if one exists. If every tried model is skipped for budget reasons, the request fails with workflow_budget_exceeded.


Overview page

The Spending limits section on Overview shows:

  • Project card — spent vs cap, remaining budget, reset time, and a config warning when any production workflow model is missing USD catalog pricing
  • Per-workflow rows — spend and cap for each capped slot, with quick edit controls
  • Summary chips — protected workflows, models running low (80%+), and models at limit

Bars turn amber around 80% utilization and red at the cap. A project can show a config warning even when spend is still low, if pricing is missing for routable models.


Soft enforcement

Spend totals are cached for about 10 seconds to keep checks fast. Under concurrency, a few extra requests can slip through before the next block — you may see spent slightly above cap in Overview or error payloads (for example $0.011797 against a $0.011 cap).

The cap value itself always comes from your saved settings. Blocks happen when cached spend is already >= cap, not based on a forecast of the current request.


Pricing must be known

Caps only work when ModelRiver has USD pricing for the model being routed.

CaseWorkflow capProject cap
USD pricing in catalogNormal enforcementNormal enforcement
Pricing unknownSlot skipped; terminal workflow_budget_config_error if nothing else can runHard block with project_budget_config_error

Overview shows a config warning when any active production workflow model lacks pricing. Fix catalog pricing or remove the cap until it is available.


When a limit blocks a request

Workflow cap — workflow_budget_exceeded (402)

All models attempted in the failover chain were skipped for budget. The response includes an attempts array with reasons like daily budget ($0.009) reached.

In Request Logs you will usually see:

  • One or more Skipped rows (response_source: budget_guardrail)
  • A parent Error row with the terminal API error payload

Project cap — project_budget_exceeded (402)

Spend hit the project cap before routing. No backups are tried. The response includes cap_usd, spent_usd, period, and reset_at.

Request Logs show a single Error row with response_source: budget_guardrail, zero tokens, and no provider call.

See Error handling for response examples and legacy error aliases (budget_exceeded, budget_config_error).


Test mode and Playground

TrafficLimits enforced?
Workflow in test modeNo
Playground + production workflowYes — counts as live spend
Playground + test-mode workflowNo

Use test mode when you want to exercise integrations without touching budgets.


Practical tips

  • Put caps on individual models first when you care about per-feature spend; add a project cap as a backstop
  • Use hourly or daily periods while tuning values, then move to weekly or monthly in production
  • After saving caps, run a few live requests and confirm Overview numbers move as expected
  • Use cost analytics to pick realistic cap values from actual log prices

Next steps