Instrument a production Next.js app with OpenTelemetry, export traces to Grafana Cloud, and handle sampling, costs, and edge cases without vendor lock-in.
Why tracing matters for lean Next.js teams
Request flows in Next.js span server components, route handlers, external APIs, and database calls. Without distributed tracing you lose visibility into latency sources and failure propagation once traffic leaves a single request.
OpenTelemetry gives you vendor-neutral instrumentation that works with Grafana Cloud today and any other backend later. The setup cost is low enough for solo founders yet scales to the patterns described in How to Deploy a Hono API to Cloudflare Workers with D1 and Queues.
Install the minimal SDK and auto-instrumentation
Use the official OpenTelemetry packages rather than third-party wrappers. The following set covers Node.js runtime, HTTP, and Postgres clients without pulling in unused exporters.
npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http
Create instrumentation.ts at the project root. This file is loaded once per process before any user code runs when you enable the instrumentation hook in next.config.js.
Configure the OTLP exporter for Grafana Cloud
Grafana Cloud accepts OTLP over HTTP on a tenant-specific endpoint. Retrieve the endpoint and API token from the Grafana Cloud stack settings; the token must have the traces:write scope.
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
headers: { Authorization: `Bearer ${process.env.OTEL_EXPORTER_OTLP_HEADERS}` },
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
Store the endpoint and token in Vercel or your deployment platform as OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_EXPORTER_OTLP_HEADERS. Never commit tokens.
Instrumenting server components and API routes
Auto-instrumentation covers most HTTP and fetch calls. For custom spans around database queries or third-party SDKs, use the tracer API directly inside route handlers or server actions.
import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('nextjs-app');
export async function GET() {
return tracer.startActiveSpan('fetch-user-data', async (span) => {
try {
const data = await db.query(...);
return Response.json(data);
} finally {
span.end();
}
});
}
Next.js server components run in the same Node process, so spans created there appear in the same trace as the incoming request.
Sampling, batching, and production gotchas
Always enable head-based sampling in production. Sending every span to Grafana Cloud quickly exceeds free-tier limits and inflates egress costs. Use the @opentelemetry/sdk-trace-base Sampler with a 0.1 ratio for most SaaS workloads.
Batching is enabled by default but tune the maxExportBatchSize and scheduledDelayMillis when you see high memory usage under load. Also set OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES so traces are correctly attributed across environments.
Client-side Next.js components cannot export directly to Grafana Cloud without a proxy; route browser spans through your own API endpoint to avoid CORS and token exposure.
Verification and integration with existing workflows
After deployment, generate traffic and open the Grafana Cloud traces explorer. Filter by service.name and look for the expected parent-child relationships between route handlers and downstream calls. Missing spans usually indicate the instrumentation hook is not enabled or the exporter URL is malformed.
Once traces are flowing, correlate them with logs and metrics using the same resource attributes. Teams that already sync external events into Postgres can join trace IDs to those records using the same idempotency patterns shown in How to Implement Idempotent Webhooks with Postgres Unique Constraints and Build a Production RAG App with Cloudflare Workers AI, Vectorize, and D1.
