Distributed Traces

See why a request was slow or failed — not just that it failed. Send OpenTelemetry traces from your app and Enori shows you the full request path, service by service.

What is distributed tracing?

Uptime monitoring tells you a check failed. Distributed tracing tells you why.

A trace is the complete story of one request as it moves through your system — the incoming HTTP call, the database queries it triggered, the downstream services it called, and how long each step took. Each step is a span; a trace is the tree of spans for a single request.

Example: your checkout API returns a 500. The uptime check tells you it's down. The trace tells you the request spent 40 ms in your API, then 4.2 seconds waiting on a payment provider that timed out — so the fix is the payment integration, not your API.

You instrument your application once with OpenTelemetry (the open standard, supported in every major language), point it at Enori, and every request your app handles becomes a searchable trace. No agent to install, no sidecar — your app pushes the data to us.


When to use it

Traces answer the questions uptime checks can't:

QuestionUptime monitorTraces
Is my service up?
Which downstream call made it slow?
Which database query is the bottleneck?
Why did this one request error while others succeeded?
Is service X slower today than yesterday?

Use traces when you run APIs or backend services and want to debug latency and errors down to the individual call — especially across a chain of microservices, or when a slow request could be your code, your database, or a third party.

You don't need traces when you only care whether a website or endpoint is reachable — that's what a Website monitor already covers, at no extra cost. Traces are a complement to uptime checks, not a replacement.


How it works

  1. You send spans. Your app's OpenTelemetry SDK batches spans and pushes them to Enori's ingestion endpoint over HTTP. You authenticate with an API key.
  2. Enori stores and indexes them — grouped into traces, searchable by service, operation name, duration, error status, or any attribute.
  3. You explore — the trace list, a service map, a per-request waterfall, and pre-built RED (Rate / Errors / Duration) health charts per service.
  4. Enori correlates its own uptime checks with your traces. Every Website and API-flow check carries a W3C traceparent header tagged enori=synthetic, so if your app is instrumented, a failed check stitches straight to the trace of that exact probe — you jump from "the check failed" to "here's the request that failed" in one click.

Traces appear on your dashboard within about a minute of your first request.

What counts, and for how long

Two numbers govern your account: a daily span quota (how many spans you can send per UTC day) and a retention window (how long stored traces are kept). Both are set by your trace tier — see Turning it on. Pre-built RED health trends are kept for 90 days on every tier, even Free.


Turning it on

Traces are included in every Enori plan at no extra cost — there's nothing to buy to get started. Every account has a Free trace tier active by default. You send traces, explore them, use the service map and health charts immediately. Only volume and retention are gated, never features.

When you outgrow the Free quota, upgrade to a paid tier:

TierPriceDaily span quotaRetentionAI trace analysis
Free (included)€025,000 spans/day7 days
Plus (add-on)€5/mo (€50/yr)200,000 spans/day14 days
Scale (add-on)€15/mo (€150/yr)750,000 spans/day30 days
  • One tier is active per account at a time. You can move up or down freely (Free ↔ Plus ↔ Scale).
  • Paid tiers are billed as a Stripe add-on on top of your plan, with prorated charges when you switch.
  • Upgrading takes effect immediately; the higher quota applies against the same day's running count.

To buy or change your tier

  1. Open Traces in the sidebar, or go to Settings → Add-ons.
  2. On the Traces page, the quota strip at the top has a Manage / Upgrade button; in Settings, the Trace add-on section has a Manage button. Either opens the tier picker.
  3. Pick Plus or Scale. For an upgrade you'll see the prorated charge before you confirm.
  4. Confirm. The new quota and retention apply right away.

Downgrading is safe. If you switch to a shorter retention (e.g. Scale → Free), Enori shows you exactly how many traces would eventually be removed and holds a grace period before anything is deleted — 7 days if you chose the downgrade, 14 days if it was caused by a failed payment. Export anything you need during the grace window.

Screenshot: the Traces page quota strip with the Upgrade button, and the tier picker modal showing Free / Plus / Scale cards.


Setting it up

Sending traces is a two-part job: create an API key, then point your app's OpenTelemetry exporter at Enori. Takes about two minutes. The Traces page has a copy-paste snippet generator for Node.js, Python, .NET, and Go — the steps below explain what it produces.

1. Create an API key with the traces:write scope

Go to Settings → API Keys and create a key that includes the traces:write scope (see Account & Settings). This is the only scope required to send traces.

The full key is shown once, at creation. Copy it then — you can't retrieve it later. If you lose it, create a new one.

2. Point your OpenTelemetry exporter at Enori

Configure your app's OTLP exporter with two values:

SettingValue
Endpointhttps://api.enori.io/api/v1/traces
Auth headerX-Enori-API-Key:

That's it — standard OpenTelemetry, no Enori-specific SDK. For example, a Node.js service:

js
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { Resource } from '@opentelemetry/resources';

const sdk = new NodeSDK({
  resource: new Resource({ 'service.name': 'my-service' }),
  traceExporter: new OTLPTraceExporter({
    url: 'https://api.enori.io/api/v1/traces',
    headers: { 'X-Enori-API-Key': 'YOUR_API_KEY' },
    compression: 'gzip',
  }),
});
sdk.start();

Transport — use OTLP over HTTP. Enori accepts OTLP/HTTP in both protobuf (recommended) and JSON encodings. OTLP/gRPC is not supported yet — if your SDK is set to gRPC, switch it to HTTP/protobuf, which is a one-line change (OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf, or the protobuf exporter package). See the FAQ.

gzip is recommended and enabled in every generated snippet — it saves 60–80% bandwidth on payloads over 1 KB at negligible CPU cost.

If you want the failed check → trace jump, set the resource attribute enori.monitor_id to the ID of the Website monitor you're tracing. This is optional — leave it out and your traces still appear on the account-wide Traces page; they just won't be linked to a specific monitor. The Traces page has a monitor picker that fills the correct ID into the snippet for you.

Linking affects future traces only (after you redeploy). Existing traces are never rewritten.

Attribute hygiene (important)

Spans carry attributes — annotate them well, but keep them clean:

Do include: http.method, http.route, db.system, db.name, status codes, durations, retry counts, and stable IDs that are hashed or redacted.

Avoid: personal data (user.email, user.id, full names), raw SQL with inline parameter values, auth tokens / passwords / session cookies, and request/response bodies over a few KB.

Enori caps attribute key length at 1 KB, value length at 2 KB, and 50 attributes per span; oversized values are truncated at ingest. A single request can carry up to 1,000 spans.

Screenshot: the "Connect a service" panel on the Traces page with the language/transport tabs and the generated snippet.


Reading the results

Open Traces in the sidebar for the account-wide view (or the Traces section on a Website monitor's detail page for the monitor-scoped view).

Trace list. Recent traces, one row each, with duration, span count, service, and error status. Filter by:

  • Service and operation name (prefix search)
  • Errors only
  • Minimum duration (find the slow ones)
  • Time range (last hour up to 90 days, or a custom window)
  • Attributes (any key/value you tagged, e.g. http.status_code = 500)

Origin pill. Each trace is tagged customer (sent by your app) or synthetic (one of Enori's own uptime probes) so you can tell real traffic from monitoring traffic at a glance.

Service map. A visual inventory of the services Enori has seen, and how they call each other — the shape of your system, discovered automatically from incoming spans.

Waterfall. Click any trace to open its span timeline: every span as a horizontal bar, nested by parent, so the critical path and the slow step are obvious. Click a span to see its full attributes. Large traces stream in as you scroll.

Service health (RED charts). Pre-built Rate / Errors / Duration-over-time charts per service, so you can answer "is this service slower than yesterday?" without writing a query. Click any bucket on the chart to drill straight into that window's traces. RED trends are kept for 90 days on every tier.

AI trace analysis (Plus and Scale)

On paid tiers, Enori can explain a trace for you. Two ways:

  • Automatically on an incident. When a monitor opens an incident and its failing check has a correlated trace, Enori analyzes that trace and attaches a plain-language root-cause summary to the incident — the "why" is waiting for you when you open the incident.
  • On demand. An Explain this trace button on any waterfall runs the same analysis for any trace you pick — slow ones and error ones alike. It takes a few seconds.

There's a fair-use cap of 25 analyses per day per account. On the Free tier the button appears as a locked upsell; analyses you've already generated stay readable if you later downgrade.


Alerts

Uptime alerts fire when a monitor goes down. RED alerts fire on the shape of your traffic — when a service's error rate spikes, its latency climbs, or its request rate drops to nothing (a "traffic gone" signal). They work on any tier as long as traces are flowing for the service.

Create a RED alert rule

  1. Open a Website monitor's detail page and find the Trace RED alerts card in the right rail. (The monitor must have at least one linked trace service — send traces tagged with its enori.monitor_id first.)
  2. Click + Add RED alert (or View management page).
  3. Pick the trace service to watch.
  4. Choose a preset (Balanced / Sensitive / Relaxed) to seed sensible thresholds, then tune. Enable at least one metric:

- Error rate — fire when error % exceeds your threshold (0–100%). - Latency — fire when p95 or p99 exceeds your threshold in milliseconds. - Low request-rate — fire when traffic drops below a floor (spans/min).

  1. Set the severity (Warning or Critical) and the evaluation parameters:

- Window (5–60 minutes) — the measurement window. - Min volume — skip evaluation below this many spans (avoids alerting on noise). - Sustained ticks (1–12) — open an alert only after this many consecutive breaching evaluations. - Recovery ticks (1–12) — auto-resolve after this many consecutive healthy evaluations.

  1. Save. Rules are evaluated about every 5 minutes.

When a rule breaches, it opens an alert episode you can acknowledge, snooze, or resolve — routed through the same alert channels (email, Slack, Discord, Teams, webhook, push) you've already configured on the monitor. See SLOs for how Enori's burn-rate alerts use the same episode model.

How many rules you can have (enabled rules, per Enori plan):

PlanEnabled RED alert rules
Base10
Pro50
Business200

Screenshot: the "New RED alert" modal with the preset picker and the three metric toggles.


FAQ / common gotchas

My traces aren't showing up

Check, in order: (1) the endpoint is exactly https://api.enori.io/api/v1/traces; (2) the X-Enori-API-Key header is set and the key has the traces:write scope; (3) your exporter uses HTTP, not gRPC (see below); (4) give it up to a minute — spans are batched by your SDK and ingested asynchronously. If you're over quota, you'll get HTTP 429 responses (see below), not silent drops.

I set gRPC and nothing arrives

OTLP/gRPC is not supported yet. Use OTLP over HTTP (protobuf recommended). In most SDKs this is a single config change — set the protocol to http/protobuf and the endpoint to https://api.enori.io/api/v1/traces.

I'm getting HTTP 429 responses

Three different limits return 429 — the response headers tell them apart:

  • Daily span quota exceeded — you've sent your tier's daily allotment. The response carries X-Enori-Quota-Limit, X-Enori-Quota-Used, and a Retry-After pointing at the next UTC midnight, when the counter resets. Upgrade your tier for a higher quota, or reduce sampling.
  • Rate limit (100 requests/minute) — you're POSTing too frequently; let your SDK batch spans (the default BatchSpanProcessor does this).
  • Backpressure (Retry-After: 5) — a brief ingestion spike; your SDK resends automatically and this consumes no quota.

What happens when I hit my daily quota?

Further spans are rejected with 429 until the next UTC midnight. Enori also sends you an in-app notification when you cross 80% and again at 100%, so it's rarely a surprise. Nothing already stored is affected.

No. enori.monitor_id is optional. Linking enables the failed check → trace jump for that monitor; unlinked traces are still fully searchable on the account-wide Traces page.

Why do I see "synthetic" traces I didn't send?

Those are Enori's own uptime probes. Every Website and API-flow check carries a trace context; when your instrumented app echoes it, the probe's request shows up as a trace tagged synthetic. It's how the check-to-trace correlation works — no action needed.

Will you keep my traces forever?

No — retention is 7 / 14 / 30 days by tier (Free / Plus / Scale). Pre-built RED health trends are kept 90 days on every tier. Export anything you need to keep longer.

Is my PII safe in spans?

Enori truncates oversized attributes at ingest, but it does not scrub PII you send — so don't put emails, tokens, or raw request bodies in span attributes in the first place. See Attribute hygiene.


Troubleshooting

SymptomLikely causeFix
No traces appear at allWrong endpoint, missing/invalid API key, or gRPC transportVerify https://api.enori.io/api/v1/traces, X-Enori-API-Key with traces:write scope, and HTTP/protobuf transport
403 Forbidden on ingestAPI key lacks the traces:write scopeRecreate the key with traces:write (Settings → API Keys)
429 with X-Enori-Quota-* headersDaily span quota exhaustedWait for UTC-midnight reset, upgrade the tier, or lower your sampling rate
429 with Retry-After: 5, no quota headersMomentary ingest backpressureNone — your SDK resends automatically; it costs no quota
Traces arrive but aren't linked to a monitorenori.monitor_id not set (or set after existing traces were sent)Add the enori.monitor_id resource attribute and redeploy; new traces will link
RED alert card says "no linked trace services"The monitor has no traces tagged with its ID yetSend traces with that monitor's enori.monitor_id, then create the rule
Attribute values look cut off ()Value exceeded the 2 KB cap (or key over 1 KB, or >50 attributes/span)Trim the attribute; move large payloads out of spans
"Explain this trace" is lockedAI analysis is a Plus/Scale featureUpgrade to a paid trace tier, or use the manual waterfall


Last updated: 2026-07-23. Feedback or corrections: support@enori.io