CostGuardProcessor
The CostGuardProcessor enforces monetary cost limits across the agentic loop, blocking or warning when a configurable cost threshold is exceeded.
It uses processInputStep to check the cost limit before each LLM call. Cost data is queried from the observability storage APIs (getMetricAggregate) for all scopes. For resource and thread scopes, it aggregates cost across runs within a configurable time window (defaults to 7 days). For run scope, it queries cost for the current trace.
For token-based limits, use TokenLimiterProcessor instead.
Supports three scoping modes:
- Run scope: Tracks cost within a single agent run via trace ID
- Resource scope (default): Tracks cumulative cost per
resourceIdacross runs - Thread scope: Tracks cumulative cost per
threadIdacross runs
Approximate cost guard. Cost data is persisted asynchronously via buffered exporters in the observability pipeline. Fast-running agents may exceed the configured limit before metrics are available for query. Treat
maxCostas a best-effort threshold, not a hard ceiling.
Usage exampleDirect link to Usage example
Track cumulative cost per resource (default scope):
import { CostGuardProcessor } from '@mastra/core/processors'
const costGuard = new CostGuardProcessor({
maxCost: 1.0,
})
Track cumulative cost per thread with a 24-hour window:
import { CostGuardProcessor } from '@mastra/core/processors'
const costGuard = new CostGuardProcessor({
maxCost: 5.0,
scope: 'thread',
window: '24h',
})
Attach to an agent with an onViolation callback:
import { Agent } from '@mastra/core/agent'
import { CostGuardProcessor } from '@mastra/core/processors'
const costGuard = new CostGuardProcessor({
maxCost: 5.0,
scope: 'resource',
window: '30d',
})
costGuard.onViolation = ({ detail }) => {
console.log(`Cost exceeded for ${detail.scopeKey}: $${detail.usage}/$${detail.limit}`)
}
const agent = new Agent({
name: 'my-agent',
model: 'openai/gpt-5-nano',
processors: {
input: [costGuard],
},
})
Constructor parametersDirect link to Constructor parameters
maxCost:
scope?:
window?:
strategy?:
message?:
Instance propertiesDirect link to Instance properties
id:
name:
onViolation?:
processInputStep:
Error behaviorDirect link to Error behavior
When the block strategy is active (default), CostGuardProcessor calls abort() with retry: false when the cost limit is exceeded. The TripWire metadata includes:
processorId:'cost-guard'usage: Current cumulative usage (estimatedCost,costUnit)maxCost: The configured cost limitscope: The active scope ('run','resource', or'thread')scopeKey: The scope identifier for resource/thread scopes (if applicable)
Scoping behaviorDirect link to Scoping behavior
| Scope | Tracks across runs | Filter | Requires context |
|---|---|---|---|
run | No | traceId from current span | Tracing context (automatic) |
resource | Yes | resourceId + time window | resourceId in RequestContext |
thread | Yes | threadId + time window | threadId in RequestContext |
All scopes require observability storage with getMetricAggregate support. If the Mastra instance does not have observability storage configured, an error is thrown at registration time.
For run scope, the processor reads the trace ID from the current span's tracing context. If no tracing context is available, the check is skipped (fail-open).
For resource and thread scopes, if the required context ID is missing at runtime, the check is skipped. Observability query failures are handled with a fail-open strategy: if a query fails, cost is treated as zero.
Note on metric persistence delay. The observability pipeline uses buffered exporters that flush metrics asynchronously. There is a short delay between when an LLM call completes and when its cost metrics are available for query. During high-frequency agent execution, the cost guard may not detect a limit breach until one or more steps after the actual cost exceeded the threshold.