Custom alerts
Custom alerts put a threshold on workspace metrics, optionally scoped by filters. A custom alert is one or more rules, always combined with AND, all evaluated over one shared rolling window. The builder shows a plain-language preview of exactly when the alert will fire, and that sentence becomes the alert’s description on its details page.

The rule grammar
FILTERS Service = checkout-agent (optional, applied before aggregation)
RULES avg(Cost) > $0.50
AND count(Errors) > 10
WINDOW 15 minutes (shared by all rules)Rules combine with AND only. There is no OR and no nesting: if you want either-or semantics, create a second alert.
Filters
Filters select which spans feed the rules, before any aggregation. Each filter matches a span’s own value, so Agent and Instance select every span that carries the value, not only root spans.
Because the rules measure only the matched spans, Step, Model, Span kind and
Operation filters change what a metric covers. Cost is on model-call spans,
so a filter that selects only tool, chain or agent spans measures no cost,
and no filter measures the cost of the model calls inside one step. To alert
on model spend, filter Model, or Span kind to LLM (add Embedding and Reranker
with in if your agent calls them). With one of these filters,
Duration runs, per trace, from the earliest matched span’s start to the
latest matched span’s end, not across the whole run. Use Service or Agent to
measure whole runs.
Text fields offer =, ≠, in, and not_in (none of the listed values), and
values are suggested from your workspace’s live data.
| Field | Matches |
|---|---|
| Service | service.name from your instrumentation |
| Agent | The agent identity Rius derives, as each span carries it |
| Step | The span name |
| Model | gen_ai.request.model |
| Span kind | LLM, tool, chain, retriever, and so on |
| Operation | gen_ai.operation.name, such as chat, execute_tool, or retrieval |
| Session | session.id |
| Instance | The process instance (service.instance.id) each span carries |
A Step filter matches span names exactly. The 1.0.0 SDKs name unnamed
tool, agent, retrieval, and model spans after their operation and target,
such as execute_tool search_orders, so an alert written against spans from
an earlier SDK needs the new name once your agents upgrade; see
Queries or alerts stopped matching.
Metrics
Metrics are typed, and the type decides which aggregations the builder offers.
| Metric | Type | Aggregations | Unit |
|---|---|---|---|
| Cost | numeric | avg, min, max, p50, p95, p99 | USD |
| Input tokens | numeric | avg, min, max, p50, p95, p99 | tokens |
| Output tokens | numeric | avg, min, max, p50, p95, p99 | tokens |
| Reasoning tokens | numeric | avg, min, max, p50, p95, p99 | tokens |
| Duration | numeric | avg, min, max, p50, p95, p99 | ms |
| Time to first token | numeric | avg, min, max, p50, p95, p99 | ms |
| Context usage | numeric | avg, min, max, p50, p95, p99 | 0 to 1, shown as % |
| Error rate | ratio | rate (a rate is already an aggregate) | 0 to 1 |
| LLM error rate | ratio | rate | 0 to 1 |
| Errors | event | count, ucount (distinct traces) | count |
| Traces | event | count, ucount | count |
| LLM calls | event | count, ucount | count |
Numeric aggregations use per-trace semantics: avg(Cost) is the average cost
per trace in the window, not the workspace total. Time to first token,
Context usage, and LLM calls are the exception: they are measured per LLM
call, so their aggregations are over calls, not traces. An LLM call is an inference call, a
span the trace view badges as LLM; agent, tool, retrieval, and embedding
spans never count, even when they carry a model. Error rate and LLM error rate are the share of
spans, or of LLM calls, that errored in the window, and you compare them
against a value between 0 and 1. Comparison operators are <, <=,
>, >=, and ==.
Context usage is the share of the model’s context window one LLM call
filled: its input tokens, prompt cache included, divided by the model’s
window. You compare it against a value between 0 and 1, so
p95(Context usage) > 0.8 fires when the fullest 5% of calls in the window
use more than 80% of their model’s context. A call whose model has no known context window has
no context usage: it is left out, never counted as 0.
An alert takes up to 10 filters with up to 50 values each, up to 10 rules, and a window between 5 minutes and 24 hours. The builder also sets the alert’s Renotify policy, off or every N minutes, described under Firing lifecycle.
Three metrics have coverage caveats. Cost is only as complete as your pricing coverage: spans whose model has no known price carry no cost. Time to first token exists only on streamed LLM calls whose instrumentation records it; see No time to first token. Context usage exists only on LLM calls whose model has a known context window. Firings on any of the three surface the coverage ratio, so you can tell a real reading from a partly covered one. Coverage is attached only to firings: a rule held under its threshold by low coverage stays quiet, so check which models are priced on Usage and cost before relying on a cost alert.
A Traces count < 1 rule over a generous window doubles as a dead-man
switch: it fires when ingestion stops entirely.
Managing custom alerts
Custom alerts get the same details page as pre-defined ones: the generated description, the editable rule, attached channels, and firings. Firings record the observed value of every rule against its threshold, so you can see which condition tripped. Unlike pre-defined alerts, a custom alert can be deleted; deleting it removes its firing history after an explicit confirmation.
Next steps
- Distribution channels: route firings to webhook, email, or Slack.
- Monitoring usage and cost: the same metrics as a summary on Home instead of as a trigger.