How-to · OpenTelemetry

How to Monitor REST and GraphQL APIs with OpenTelemetry

Monitoring REST and GraphQL APIs with OpenTelemetry means instrumenting the HTTP and GraphQL layer to emit traces and metrics over OTLP, so API health, latency and errors are fully observed..

Monitoring REST and GraphQL APIs with OpenTelemetry means instrumenting the HTTP and GraphQL layer to emit traces and metrics over OTLP, so API health, latency and errors are fully observed.

What to observe in a REST or GraphQL API

APIs are the contract with your consumers, so the golden signals apply directly: request rate, error rate, latency (p50/p95/p99) and saturation, per endpoint and, for GraphQL, per operation and resolver. GraphQL adds a twist, a single HTTP endpoint hides many operations, so aggregate endpoint metrics tell you almost nothing and you need resolver-level detail to find what is slow.

The reading that resolves most API incidents is per-endpoint (or per-operation) latency percentiles alongside the downstream call inside the request, because API latency is usually a specific slow dependency, and for GraphQL a specific slow resolver, not the API layer itself.

How OpenTelemetry collects it

REST APIs are well covered by OpenTelemetry HTTP auto-instrumentation, so each route emits a server span and metrics over OTLP with little effort, and downstream calls become child spans. For GraphQL you add the GraphQL instrumentation for your server, which creates a span per operation and per resolver, so you can see which query and which resolver is slow behind the single endpoint.

The GraphQL-specific caution is cardinality and naming: capture the operation name (not just the endpoint) so operations are distinguishable, and be careful that resolver-level spans on high-volume APIs can generate a lot of data, so sample sensibly while keeping the operation-level metrics complete.

Metric and attribute names follow OpenTelemetry HTTP and GraphQL conventions and can vary by instrumentation version.

Key metrics to watch

The signals that explain most API incidents:

SignalSourceWhat it tells you / watch for
http.server.request.durationHTTP instrumentationPer-endpoint latency histogram; for REST this is your primary latency signal.
error rate by route / operationHTTP / GraphQL instrumentation4xx and 5xx per endpoint or GraphQL operation; separates client from server faults.
GraphQL operation durationGraphQL instrumentationLatency per named operation, the GraphQL equivalent of per-endpoint timing.
GraphQL resolver durationGraphQL instrumentationLatency per resolver; reveals the specific field that is slow behind an operation.
resolver call count per requestGraphQL instrumentationMany calls to one resolver in a request is the GraphQL N+1 pattern.
downstream span durationclient instrumentationLatency of DB and service calls inside a request; usually where the time goes.

What to put on a dashboard

An API dashboard should work for both REST and GraphQL. Row one: request rate and error rate by endpoint or operation, and p95/p99 latency by endpoint or operation. Row two, for GraphQL: slowest resolvers and resolver call counts per request to catch N+1. Row three: downstream call latency by target, since that is where most API latency actually lives.

# p99 latency by endpoint (REST) or operation (GraphQL)
histogram_quantile(0.99, http.server.request.duration) by (http.route)

# error rate by route/operation
sum(rate(http_server_requests{status=~"5.."}[5m])) by (http.route)
  / sum(rate(http_server_requests[5m])) by (http.route)

# GraphQL resolver latency (find the slow field)
histogram_quantile(0.95, graphql.resolver.duration) by (field)

Reading the signals: common failure modes

Slow resolver hiding behind a fast endpoint

A GraphQL API looks fine at the endpoint level but specific queries are slow, because one resolver is expensive. Resolver-level spans expose the slow field, which aggregate endpoint metrics never would. Optimise or cache that resolver.

GraphQL N+1

One operation is slow and its trace shows a resolver called many times, once per item in a list, each making its own database call. The resolver call count per request is the tell. Batch the loads (a dataloader pattern) so the list resolves in one query, not N.

Slow downstream dependency

An endpoint's p99 rises and the added time is in a specific downstream span, a database query or an upstream API, while the API layer itself is fast. The fix is in the dependency; the trace makes that unambiguous rather than leaving you to tune the API.

Example alert conditions

Starting thresholds to tune:

ConditionSignalMeaning
5xx rate by route/operation > 2% for 5merrorsAn endpoint or operation is failing.
p99 latency > SLO for 10mlatencyAn endpoint or operation regressed.
resolver call count per request spikingGraphQLAn N+1 pattern has appeared.
downstream p95 > SLOdependencyA dependency is the bottleneck.

From monitoring to autonomous resolution

Ops Singularity's TelemetryOps ingests API telemetry over OpenTelemetry, and Sentinel AI resolves the API incidents it reveals through governed Action Tickets validated by Sherlock. Explore TelemetryOps and ServiceOps.

Frequently asked questions

How do I monitor a REST API with OpenTelemetry?

Use OpenTelemetry auto-instrumentation for your HTTP framework so each route emits traces and metrics over OTLP, then watch per-endpoint latency percentiles and error rates.

How do I observe GraphQL with OpenTelemetry?

Use the GraphQL instrumentation for your server so each operation and resolver becomes a span, revealing which query and resolver is slow behind the single GraphQL endpoint.

See autonomous operations on your own stack.

Bring a real incident. We will show you Sentinel investigate, act and verify end to end, with every action reversible and audited.

Request a Demo → See TelemetryOps