Every agent run,
end to end.
Cinder traces every model call, tool invocation, retry and fallback in your stack — with latency, token cost and error attached to each span.
npm i @cinder/otel- SOC 2 Type II
- OpenTelemetry-native
- Self-host or cloud
In production at
- Verity Labs
- Northbeam
- Lumen Freight
- Tessera
- Ardent
- Quillwork
99.98% ingestp99142 ms
02 — surface
Five things you stop guessing about
Every cell here is a real surface in the product, not an illustration of one.
142 ms
p99 query latency across a 30-day window
Down from 380 ms after the attribute index moved off the hot path.
Sampling that keeps the incident
Deterministic by trace ID, with errors and slow spans escalated regardless of rate.
6.8% retained after escalation
Already instrumented?
Point an OTLP exporter at us. No vendor SDK required.
OTEL_EXPORTER_OTLP_ENDPOINT=
https://in.cinder.devWhere the time goes
Share of wall time by span kind, last 24 hours.
- model48%
- tool31%
- i/o17%
- failed4%
Slowest spans
Ranked by p99, filtered to spans you own.
| model.completion | 1,442 ms |
|---|---|
| retrieve.clauses | 86 ms |
03 — install
Eleven minutes, including reading the docs
One decorator, one wrapper, or an environment variable if you already speak OTLP.
- Under a millisecond on the calling thread, measured at p99.
- Spans batch on a background worker and drop rather than block.
- Redaction runs in your process, before anything is transmitted.
from cinder import trace, init
init(api_key=CINDER_API_KEY)
@trace
def review_contract(doc: str) -> Review:
clauses = retrieve(doc) # span: retrieve.clauses
return compare(doc, clauses) # span: agent.compareimport { init, trace } from '@cinder/sdk';
init({ apiKey: process.env.CINDER_API_KEY });
export const reviewContract = trace(
'review_contract',
async (doc: string) => {
const clauses = await retrieve(doc);
return compare(doc, clauses);
},
);import "github.com/cinder-dev/cinder-go"
func main() {
cinder.Init(cinder.Config{APIKey: apiKey})
}
func ReviewContract(ctx context.Context, doc string) (*Review, error) {
ctx, span := cinder.Start(ctx, "review_contract")
defer span.End()
clauses, err := Retrieve(ctx, doc)
if err != nil {
return nil, err
}
return Compare(ctx, doc, clauses)
}# Already instrumented? Point your exporter at us
# and change nothing else.
export OTEL_EXPORTER_OTLP_ENDPOINT="https://in.cinder.dev"
export OTEL_EXPORTER_OTLP_HEADERS="x-cinder-key=${CINDER_API_KEY}"04 — proof
We had a retrieval step silently returning empty results for about four percent of requests. It never threw. Cinder showed the span duration collapsing to nothing and we found it in an afternoon.
05 — ledger
p99 by span kind, not by service
Service-level latency hides which step is slow. Span-kind latency does not.
| Span kind | Spans | p50 | p99 | Share of wall time |
|---|---|---|---|---|
| model.completion | 28.4B | 612 ms | 1,442 ms | 48% |
| tool.invoke | 18.1B | 94 ms | 410 ms | 31% |
| retrieve.query | 9.7B | 41 ms | 86 ms | 17% |
| model.retry | 2.4B | 780 ms | 2,110 ms | 4% |
Ship agents you can actually debug.
Five million spans a month, free permanently. No card, no trial clock.
npx @cinder/cli initOr talk to an engineer — the same people who wrote the ingest path.