Introduction
Honeycomb is a modern observability platform that excels at analyzing high-cardinality data. Unlike traditional solutions, it allows quick exploration of distributed traces and identification of bottlenecks without indexing all metrics in advance. In 2026, integration via OpenTelemetry has become the standard. This tutorial guides you step by step to instrument a Node.js application, send traces, and create relevant dashboards. You will learn how to configure the SDK, manage attributes, and analyze data in real conditions.
Prerequisites
- Node.js 20+ and TypeScript
- Honeycomb account with API key
- Basic knowledge of OpenTelemetry
- Existing Express or Next.js application
Install Dependencies
npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-httpThese packages install the OpenTelemetry SDK, automatic instrumentations, and the exporter compatible with Honeycomb. Avoid incompatible versions by using recent releases.
Configure the Tracer
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
const exporter = new OTLPTraceExporter({
url: 'https://api.honeycomb.io/v1/traces',
headers: { 'x-honeycomb-team': process.env.HONEYCOMB_API_KEY || '' }
});
const sdk = new NodeSDK({
traceExporter: exporter,
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start();This file initializes the SDK and sends traces to Honeycomb. The HONEYCOMB_API_KEY environment variable must be set. Never hardcode the key in source code.
Manual Instrumentation of a Route
import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('my-service');
app.get('/api/users', async (req, res) => {
const span = tracer.startSpan('get-users');
try {
const users = await fetchUsers();
span.setAttribute('user.count', users.length);
res.json(users);
} catch (error) {
span.recordException(error);
res.status(500).send('Error');
} finally {
span.end();
}
});Manual instrumentation adds business attributes such as the number of users. This enriches Honeycomb traces and makes filtering by high cardinality easier.
Docker Configuration for Production
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
ENV HONEYCOMB_API_KEY=${HONEYCOMB_API_KEY}
ENV OTEL_SERVICE_NAME=my-app
CMD ["node", "--require", "./tracing.js", "dist/index.js"]This Dockerfile injects the API key and service name at runtime. Always use environment variables for secrets in production.
Create a Honeycomb Dataset
curl -X POST https://api.honeycomb.io/1/datasets \
-H "X-Honeycomb-Team: $HONEYCOMB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "production-traces"}'This command creates a dedicated dataset for traces. Organize your environments (prod, staging) in separate datasets for better data isolation.
Best Practices
- Always use standard OpenTelemetry semantic attributes
- Limit attribute cardinality to fewer than 1000 distinct values
- Configure sampling rates suited to your traffic volume
- Add spans for critical external calls
- Document service names and versions in attributes
Common Errors to Avoid
- Forgetting to call span.end() which leaves incomplete traces
- Not propagating context in asynchronous calls
- Exposing the API key in the frontend
- Ignoring Honeycomb exporter connection errors
Going Further
Discover our advanced training on modern observability and Honeycomb at Learni Group.