Distributed Tracing Setup for Microservices (Jaeger/Zipkin)

Note: when p95 latency of a microservice API unexpectedly spikes to 10 seconds and logs in Order Service are perfectly clean — the ghost hunt begins. In such situations, we deploy distributed tracing: OpenTelemetry + Jaeger (or Zipkin) for full visibility. More about distributed tracing can be found

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • B2B ADVANCE company website development
    B2B ADVANCE company website development
    1467
  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1318
  • Website development for BELFINGROUP
    Website development for BELFINGROUP
    1015
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1276
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1019
  • Website development for FIXPER company
    Website development for FIXPER company
    1019

Note: when p95 latency of a microservice API unexpectedly spikes to 10 seconds and logs in Order Service are perfectly clean — the ghost hunt begins. In such situations, we deploy distributed tracing: OpenTelemetry + Jaeger (or Zipkin) for full visibility. More about distributed tracing can be found on Wikipedia. Each request leaves a digital trail across all services — from API Gateway to Payment Service — with timestamps. You see that 80% of time is spent on a single Elasticsearch query, not on distributed locking. After implementation, clients reduce diagnosis time from three weeks to two days — 3x faster. One client achieved a significant reduction in annual costs by minimizing downtime. Another client with 25 microservices cut diagnosis time by 70%.

What Problems Distributed Tracing Solves

A typical situation: an N+1 query in Inventory Service turns response into 5 seconds. Or Redis cache fails due to wrong TTL — a trace will show missing cache hit. Distributed tracing reveals time in each service, DB calls (PostgreSQL, MongoDB), external APIs, and context propagation. You see that 80% of time goes to one Elasticsearch query, not distributed locking. We configure tracing to identify bottlenecks in hours, not weeks. Concrete example: for a client with 15 microservices, distributed tracing showed that 40% of requests hung due to wrong timeout in the HTTP client. Fix took 2 hours instead of a week of guesswork.

Why OpenTelemetry is the De-facto Standard?

OpenTelemetry (OTel) is a vendor-neutral SDK that lets you send traces to any backend without code changes. We use it in all projects: integrate once, then choose Jaeger for dev, Datadog for prod — no rewriting. Support now covers 20+ languages and integrations. Compared to proprietary SDKs, OpenTelemetry reduces integration time by 2x and simplifies backend migration. Our experience on dozens of projects confirms this approach's reliability.

How to Implement OpenTelemetry in Node.js: Step-by-Step

  1. Install packages: npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http.
  2. Create a tracing.ts file (import first).
  3. Configure exporter: specify Jaeger or other backend URL.
  4. Add auto-instrumentations for HTTP, Express, PostgreSQL, Redis, etc.
  5. Start SDK with sdk.start().

Example initialization for Order Service:

// tracing.ts — initialize, import before everything else import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; const sdk = new NodeSDk({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'order-service', }), traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://jaeger:4318/v1/traces', }), instrumentations: [ getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-http': { enabled: true }, '@opentelemetry/instrumentation-express': { enabled: true }, '@opentelemetry/instrumentation-pg': { enabled: true }, '@opentelemetry/instrumentation-redis': { enabled: true }, }), ], }); sdk.start(); 

Auto-instrumentations intercept Express, pg, redis, axios without writing code.

Manual Span Creation

For business operations not covered by auto-instrumentation:

import { trace, SpanStatusCode, context } from '@opentelemetry/api'; const tracer = trace.getTracer('order-service'); async function processOrder(orderId: string): Promise<void> { const span = tracer.startSpan('processOrder', { attributes: { 'order.id': orderId, 'service.operation': 'process' } }); try { await context.with(trace.setSpan(context.active(), span), async () => { const order = await loadOrder(orderId); // child span created automatically await validateOrder(order); await reserveInventory(order); // call to another service with propagation await chargePayment(order); }); span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error.message }); throw error; } finally { span.end(); } } 

How to Choose a Backend: Jaeger or Zipkin?

Zipkin Jaeger
Storage MySQL, Elasticsearch, Cassandra Elasticsearch, Cassandra, Kafka
UI Basic Richer
OTel support Yes Native
Sampling Basic Advanced

For new projects — Jaeger. Zipkin if already in use or compatibility needed. Jaeger is on average 1.5–2x faster to deploy and provides more detailed dashboards. We guarantee the chosen backend will be optimally integrated into your infrastructure.

How to Configure Sampling Under Load?

OpenTelemetry Specification recommends head-based sampling for high-load systems.

Strategy Capture % Resources When to Use
Head-based (probabilistic) 1–10% Low High-traffic systems with large trace volume
Tail-based 100% with filtering High Need all error traces, rare events

Example of head-based sampling configuration with OpenTelemetry:

import { ParentBasedSampler, TraceIdRatioBased } from '@opentelemetry/sdk-trace-base'; const sampler = new ParentBasedSampler({ root: new TraceIdRatioBased(0.1) }); 

This traces 10% of requests, but always if parent is already traced.

Tail-based sampling configuration example with OpenTelemetry Collector

Tail-based sampling requires OpenTelemetry Collector with tail_sampling processor. Configuration:

processors: tail_sampling: decision_wait: 30s num_traces: 100 expected_new_traces_per_sec: 10 policies: - name: sample_errors type: status_code properties: status_codes: [ERROR] - name: sample_slow type: latency properties: threshold_ms: 500 

What’s Included in Tracing Setup?

We provide:

  • Selection and deployment of a backend (Jaeger/Zipkin) with storage (Elasticsearch/Cassandra)
  • Integration of OpenTelemetry SDK with auto-instrumentations for all services
  • Manual instrumentation of critical business operations
  • Context propagation configuration via HTTP headers (W3C Trace Context)
  • Sampling configuration under load
  • Operations documentation and Grafana dashboards
  • Team training on working with traces

Estimated Timelines

  • OpenTelemetry SDK + Jaeger + auto-instrumentations for 3–5 services: 3–5 days
  • Manual instrumentation of business operations + sampling configuration: additional 3–5 days
  • Alert setup on p95 latency via Prometheus + Grafana: 2–3 days

Get an engineer consultation — well help choose the optimal backend and configure tracing for your architecture. Order turnkey tracing — and youll get a complete picture of microservice performance. Contact us to assess your project and learn how distributed tracing will cut debug time in your system.