01 — platform
An instrument, not a dashboard
Four surfaces that share one data model: every eval score, every dollar and every alert points back at a span you can open.
Instrumented by
- Verity Labs
- Northbeam
- Lumen Freight
- Tessera
- Ardent
- Quillwork
99.98% ingestp99142 ms
02 — tracing
Structure first, content second
A run that normally makes four tool calls and made eleven is interesting before you read a single prompt. Cinder records the shape of every run — counts, durations, stop reasons, branch decisions — so anomalies surface without payload capture.
- Retrieval spans carry chunks returned, requested, and the lowest score that made the cut.
- Model spans carry the stop reason, including tool calls truncated mid-argument.
- Decision spans record the branch taken and, where cheap, the branches not taken.
03 — evaluation
Evals that run against production, not a museum
A fixed evaluation set drifts away from reality the moment you stop curating it, and you will stop curating it. Cinder runs the same rubrics in CI and against sampled production traces, so a green check means something.
- Rubrics produce labels with written criteria, not a made-up one-to-ten score.
- Every rubric publishes its human-agreement number next to every score it produces.
- Graders are pinned. Change one and we re-grade history rather than leave a silent step in your chart.
from cinder.evals import rubric, Label
@rubric(name="citation_support", grader="claude-sonnet-4-5")
def citation_support(trace) -> Label:
"""Does every citation support the claim it is attached to?"""
if not trace.spans["retrieve.clauses"].attrs["chunks.returned"]:
return Label.UNSUPPORTED
return Label.from_grader(trace.output)
# Runs in CI against a fixed set, and hourly against
# sampled production traces. Same code path, both times.04 — cost
Cost attribution without sending us your prompts
Attach a tenant identifier at the root span and every child inherits it. Cost is derived from token counts and the model that actually served the request — including Bedrock inference profiles, which resolve to the real model rather than the profile you asked for.
- Payload capture is opt-in per attribute; redaction runs inside your process.
- Break spend down by tenant, span kind or time window with no per-call plumbing.
- Hourly Parquet exports to a bucket you own, in a schema we version and document.
Inference spend by tenant, last 30 days
- tenant 41 · Meridian Clinics$18,402
- tenant 08 · Harbor Network$11,715
- tenant 23 · Cedar Health$7,530
- 61 other tenants$46,001
05 — alerting
Alerts that open the evidence, not a dashboard
Every alert links to the failing trace. The first click is what happened, rather than a starting point for correlating four charts by eye at two in the morning.
- Route eval regressions and latency breaches to the right rotation.
- Low-tail duration flags catch the failures that present as suspicious speed.
- Signed webhook payloads for anything we have not built an integration for.
! low-tail duration flag
retrieve.clauses
completed in 3 ms · historical p50 62 ms, p05 41 ms
affects 4.1% of traces · first seen 6 weeks ago
open trace 8f2c1a4e ↗
06 — install
Two commands to the first trace
There is no agent to deploy and no collector to run. Install the SDK, wrap the entrypoint, and the first run shows up with its spans already attributed.
- Works against an existing OpenTelemetry setup — point an OTLP exporter at us instead.
- The CLI streams the trace summary to your terminal, so you never leave the shell to check.
- Flags surface at the point of failure, with the expected range beside the measured one.
pip install cinder
Successfully installed cinder-2.4.0
cinder run -- python review.py
trace 8f2c1a4e 2.84s 9 spans $0.041
! retrieve.clauses 3ms chunks.returned = 0
expected 40-90ms · 1 flag · view trace ↗
Questions engineers actually ask
How much latency does the SDK add?
0.4ms at p99 in our benchmarks, measured on the calling thread. Spans are batched and flushed on a background worker; if the flush fails, it fails quietly and drops rather than blocking your request path.
Can I keep prompts and responses out of Cinder?
Yes. Payload capture is opt-in per span attribute, and the SDK ships a redaction hook that runs before anything leaves your process. Teams in regulated industries typically send structure and timing only — the trace shape is still useful without the content.
How does sampling interact with tracing?
Sampling decisions are made at the root span and propagated, so you never get a trace with holes in it. Errors and slow traces are always kept regardless of the sample rate.
Do you offer self-hosting?
On Enterprise, yes — a Helm chart for your own Kubernetes cluster, with ClickHouse and object storage you provide. Version support runs 12 months behind the hosted product because we will not ship you something we have not run ourselves for a while first.
What exactly is an eval here?
A function that scores a trace. It can be a string check, a numeric threshold, or a model-graded rubric. Evals run against real production traces on a schedule or against a fixed set in CI. The important part is that both use the same code path, so a CI pass means something.
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.