Skip to Content
architectureobservabilityjavakubernetes

Zero-Overhead Distributed Tracing with OpenTelemetry

AUTHENTICATED_ACCESS_GRANTED

The Context: "The 3 AM Trigger"

It was October 2023. Our multi-tenant SaaS application, "CloudLedger," had just broken the monolith into 40 distinct microservices. The migration was a success right up until a top-tier client experienced intermittent 12-second latency spikes during report generation. We had application logs, we had database metrics, we had Kubernetes pod states, but we had absolutely no way of tying a specific user request across 10 network hops. It took 3 engineers 8 hours grepping through Splunk just to realize a downstream service was waiting 11.5 seconds on an external DNS timeout. That's a baigan ka debugging process. We needed distributed tracing, but we couldn't tolerate the CPU overhead of traditional APM agents parsing every bytecode instruction.

The Problem Statement

Our telemetry rollout had strict constraints:

  • Overhead: APM agent overhead must be under 3% CPU and 50MB RAM per JVM.
  • Trace Context: Must propagate seamlessly across WebFlux, Virtual Threads, and Kafka messages.
  • Cost: 100% sampling during peak loads (20k TPS) without bankrupting our logging budget.
  • Ecosystem: Must maintain low interference with the ZGC garbage collector.

Visual Architecture

The Core Logic / Process

Data Flow

Instead of hardcoding Zipkin dependencies into our applications, we attached the OpenTelemetry (OTel) Java Agent to the JVM args. The agent automatically instruments inbound endpoints, outbound JDBC calls, and Kafka producer envelopes via bytecode manipulation. When a request hits the Gateway, the OTel agent generates a W3C traceparent header.

This is crucial: when Service A drops an event onto a Kafka topic, the OTel agent intercepts the ProducerRecord, injects the traceparent into a Kafka Header, and the subsequent Consumer extracts it seamlessly, maintaining the single trace view.

Concurrency & Locking

The real challenge was the telemetry backend. Standard setups have agents sending spans directly to a vendor like Datadog, which causes massive blocking I/O on the app threads if the network degrades. We deployed an OpenTelemetry Collector as a Kubernetes DaemonSet (one per node). The Java agents simply fire-and-forget UDP packets or non-blocking gRPC calls to localhost:4317. The Collector, written in Go, buffers the spans, processes them locally, and assumes the heavy lifting of TLS shipping over the WAN to Jaeger. The java application thread is totally unaware.

Failure Modes

What happens to sampling when traffic 10x's? We employ Tail-Based Sampling at the Collector level. We record 100% of the spans locally on the node. The Collector waits 30 seconds for the entire trace to coalesce. If the trace represents a successful, sub-10ms request, it discards it. It only forwards error traces or P99 latency outliers over the WAN to long-term storage.

The "Baigan" Take (Expert Insights)

Look, setting up the OpenTelemetry Java Agent is mostly plug-and-play until you upgrade to Java 21 Virtual Threads.

Traditional tracing relied entirely on ThreadLocal storage to keep track of the current span. When you use Virtual Threads, thousands of threads are parked and unparked onto carrier threads rapidly. The older ThreadLocal approach leaks context across requests. In production, we started seeing traces where a 'payment execution' span showed up under a 'user profile query' trace ID. Absolute chaos. We had to aggressively upgrade the OTel Java instrumentations to versions that natively utilized the Java 21 ScopedValue API (JEP 429), explicitly isolating the trace context to the dynamic lexical scope of the virtual thread.

Performance Checklist

  • Use -javaagent:opentelemetry-javaagent.jar attached during JVM startup.
  • Upgrade OTel agent versions to ensure compatibility with Virtual Threads' ScopedValues.
  • Offload WAN shipping by running an OTel Collector DaemonSet on every K8s node.
  • Implement Tail-Based Sampling at the Collector to avoid massive storage bills.
© 2026 PRANABESH_VAULT_ENCRYPTION_V4CONFIDENTIAL_REPRODUCTION_PROHIBITED