The purpose of this article is to demonstrate how to quickly deploy Jaeger and explain the deployment nuances we encountered. We'll cover what Jaeger actually is, why it matters, and the specific configuration decisions that made our setup production-ready.
What is Jaeger and why is it needed?
Jaeger is a distributed tracing system designed to help developers monitor and troubleshoot microservices-based applications. It tracks requests as they move through multiple services, provides a comprehensive view of your application's behaviour, and lets you pinpoint exactly where latency or failures originate.
- Performance bottleneck identification across service boundaries
- Root cause analysis during incidents — no more guessing which service failed
- Release validation — confirm a new deployment didn't introduce regressions
- Capacity planning based on real request flow data
- Security compliance through full request audit trails
It's particularly well-suited for cloud-native and containerised environments where requests touch dozens of services before returning a response.
Our deployment approach
We rely on officially maintained Helm charts for all our Jaeger deployments. Despite the chart's size, it's straightforward to adjust for your specific needs. Here's the minimal setup to get started:
helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
helm repo update
helm install my-jaeger jaegertracing/jaeger --version 0.71.14We pin to a specific chart version rather than tracking 'latest'. This makes deployments reproducible and prevents surprise breaking changes in production.
Configuration challenges and how we solved them
The first real challenge was storage. Traces accumulate fast in a busy system, and Jaeger needs a backend that can handle high write throughput without becoming a bottleneck. We chose Cassandra, running two instances per deployment.
Each Cassandra instance runs with conservative resources that still handle production load comfortably:
- 1 vCPU per instance
- 2 GB memory per instance
- 20 GB persistent storage per instance
The key lesson here: solutions provided in official charts don't always work out of the box. We had to configure Jaeger to start cleaning up old traces once storage crossed 80% utilisation. Without this, Cassandra would fill up and Jaeger would stop accepting spans entirely — silent data loss in production.
# values.yaml — storage cleanup configuration
storage:
type: cassandra
cassandra:
keyspace: jaeger_v1_dc1
# Trigger TTL-based cleanup before storage fills
maxTraceAge: 168h # 7 days
host: cassandra-service
port: 9042What we learned
Jaeger is straightforward to get running but requires careful attention to storage limits and data retention policies before going to production. Start with a small retention window and expand it as you understand your actual trace volume. Two Cassandra nodes give you redundancy without significant resource overhead.