Skip to content
Go back

SigNoz vs Jaeger for Tracing

By SumGuy 12 min read
SigNoz vs Jaeger for Tracing
Contents

You’ve Got Traces. Now What?

Jaeger wins if you already run Prometheus, Grafana, and Loki and just need tracing bolted on, and SigNoz wins the moment you want traces, metrics, and logs correlated in one place.

You set up Jaeger. You’re shipping spans from your services. You can finally see that checkout-service is calling inventory-service four times when it should be calling it once, and that payment-gateway takes 800ms every time that one Redis key is cold.

Beautiful. Traces are working.

Then at 2 AM, your alerting fires. You open Jaeger, find the bad trace, and… now what? You tab over to Grafana for metrics. You tab over to Kibana for logs. You’re trying to correlate a trace ID manually across three UIs while your eyes are burning.

This is the gap that SigNoz is filling. And whether that gap matters to you depends entirely on what you already have.

Full example: Clone the working files at github.com/KingPin/sumguy-examples/observability/signoz-vs-jaeger


What Jaeger Actually Is (and Isn’t)

Jaeger is a CNCF graduated project, that “graduated” badge means it’s been around long enough, has enough production users, and is stable enough that the CNCF considers it done. Not stagnant, done. It does one thing: distributed tracing.

No metrics collection. No log ingestion. No alerting. No dashboards beyond traces. That’s not a knock; that’s the design. Jaeger’s job is to receive traces, store them, and let you query and visualize them. It does that job well.

Jaeger v1 vs v2, Worth Knowing

The classic Jaeger stack has a collector, a query service, and a UI, all running separately or as an all-in-one binary. Storage backends are pluggable: Cassandra (the original default), Elasticsearch/OpenSearch, or Badger (embedded, good for single-node dev setups).

Jaeger v2 is a rewrite built directly on top of the OpenTelemetry Collector. Instead of running its own collector binary, it ships as an OTel Collector distribution with Jaeger-specific extensions bolted on. This is actually a big deal, it means the same OTLP pipeline you’d use for any OTel-native tooling just works. Same config format, same receiver/exporter model, same tail-sampling extensions.

For new deployments, lean toward v2. For existing Jaeger setups that are working fine, no urgent pressure to migrate.

Spinning Up Jaeger (the easy way)

For local dev or a single-node home lab, the all-in-one image is the fastest path:

Terminal window
docker run -d --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
jaegertracing/all-in-one:latest

Port 16686 is the UI. Ports 4317 (gRPC) and 4318 (HTTP) are OTLP receivers. That’s it. Traces in, flame graphs out.

For anything beyond “I’m just testing this,” you want Compose with a real storage backend. Here’s a minimal Elasticsearch-backed setup:

docker-compose.yml
services:
elasticsearch:
image: elasticsearch:8.13.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms512m -Xmx512m
volumes:
- es_data:/usr/share/elasticsearch/data
jaeger:
image: jaegertracing/all-in-one:latest
environment:
- SPAN_STORAGE_TYPE=elasticsearch
- ES_SERVER_URLS=http://elasticsearch:9200
ports:
- "16686:16686"
- "4317:4317"
- "4318:4318"
depends_on:
- elasticsearch
volumes:
es_data:

Memory footprint on this: Jaeger itself is genuinely light, under 100MB. Elasticsearch is the resource pig. If you’re on constrained hardware, consider Badger (embedded) for dev or OpenSearch with reduced heap.


What SigNoz Actually Is

SigNoz is an open-source observability platform. It does traces, metrics, and logs in one tool, with a single UI and correlation built in. Think of it as the open-source answer to Datadog, without the per-seat pricing that makes finance people cry.

Under the hood, SigNoz uses ClickHouse as its storage layer. ClickHouse is a columnar OLAP database that handles time-series and log data well. It’s why SigNoz can do fast aggregations across millions of spans or log lines, ClickHouse is built for exactly that query shape.

The data ingestion path runs through the OTel Collector (SigNoz ships its own distribution called otel-collector). Your services send OTLP to SigNoz’s collector, and it routes spans, metrics, and logs to ClickHouse with the appropriate schema for each signal type.

What SigNoz Adds Over Jaeger

Spinning Up SigNoz

SigNoz publishes an official Compose file. This is the condensed version of what matters:

docker-compose.yml
services:
clickhouse:
image: clickhouse/clickhouse-server:24.1.2
volumes:
- clickhouse_data:/var/lib/clickhouse
ulimits:
nofile:
soft: 262144
hard: 262144
otel-collector:
image: signoz/signoz-otel-collector:0.88.11
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317"
- "4318:4318"
depends_on:
- clickhouse
query-service:
image: signoz/query-service:0.45.0
environment:
- ClickHouseUrl=tcp://clickhouse:9000
- STORAGE=clickhouse
ports:
- "8080:8080"
depends_on:
- clickhouse
frontend:
image: signoz/frontend:0.45.0
ports:
- "3301:3301"
depends_on:
- query-service
volumes:
clickhouse_data:

The actual SigNoz repo has a more complete setup with init scripts and health checks, pull from their GitHub rather than hand-rolling this for production. But that’s the skeleton.

Memory footprint is notably higher: ClickHouse alone wants 2-4 GB RAM comfortably. Expect 4-8 GB total for a production SigNoz deployment. This is not a Raspberry Pi project.


Sending Traces to Either Tool (It’s the Same Code)

The important point about OTLP: your instrumentation code doesn’t care whether it’s talking to Jaeger or SigNoz. Both speak OTLP. You point the exporter at the right endpoint and move on.

instrumentation.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
# Change this endpoint to switch between tools:
# Jaeger: http://localhost:4317
# SigNoz: http://localhost:4317 (same port, different backend)
exporter = OTLPSpanExporter(endpoint="http://localhost:4317", insecure=True)
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my-service")
with tracer.start_as_current_span("do-the-thing") as span:
span.set_attribute("user.id", "42")
span.set_attribute("item.count", 7)
# your actual logic here

Same deal with the OTel Go SDK, Java agent, Node.js SDK, OTLP is OTLP. This is one of the genuinely good things about the OTel ecosystem: you instrument once and can swap backends later.

For the OTel Collector config pointing at SigNoz, you’d add a signoz exporter section. For Jaeger v2, you configure it as a Jaeger extension within the OTel Collector pipeline. Either way, your app code doesn’t change.


The Actual Comparison

Feature Matrix

FeatureJaegerSigNoz
Distributed tracingYes (core feature)Yes
MetricsNoYes (OTel + Prometheus)
LogsNoYes (structured, OTLP)
Trace-log correlationNoYes (built-in)
Trace-metric correlationNoYes (built-in)
AlertingNo (none native)Yes (built-in)
Service mapBasicRich (with error rates)
OTLP ingestionYes (v1+, native in v2)Yes
Storage backendCassandra / ES / BadgerClickHouse
UI qualityExcellent flame graph viewerExcellent + more panels
Tail-based samplingYes (via OTel Collector)Yes (via OTel Collector)
Resource footprintLow (Jaeger ~100MB)Higher (ClickHouse 2-4GB+)
CNCF statusGraduatedNot a CNCF project (open source)
Setup complexityLowMedium

Storage: Pluggable vs Opinionated

Jaeger gives you choices: Cassandra for scale, Elasticsearch/OpenSearch for full-text search and flexibility, or Badger for single-node simplicity. This is great if you already have one of those running.

SigNoz is opinionated: ClickHouse. This is actually fine in practice, ClickHouse is very good at what SigNoz needs. But it means you’re running ClickHouse whether you like it or not. If you already have Elasticsearch in your stack and were hoping to reuse it, SigNoz won’t accommodate that.

The Correlation Story

This deserves its own section because it’s where the tools really diverge in daily use.

With Jaeger + Prometheus + Loki, you technically have all three signals. But correlation is manual. You see a trace ID in Jaeger, you copy it, you go to Loki and search for that trace ID in your log field, and you find the log lines. If you’ve instrumented everything correctly and logged the trace ID consistently. Which is more effort than it sounds at 2 AM.

SigNoz does this natively because it controls all three pipelines. Span attributes, log fields, and metric labels share context. The UI can jump between them. This sounds like a convenience feature until you’ve spent 40 minutes chasing a bug that correlation would have solved in 4 minutes.

Alerting

Jaeger has no alerting. Zero. Nada. You need to run Alertmanager or Grafana Alerting separately, write recording rules to turn trace data into metrics, and then alert on those metrics. It’s doable but it’s plumbing.

SigNoz ships with alerting built in. You can alert on P99 latency from trace data, error rate from spans, log patterns, or metric thresholds, all from the same UI. If you’re building out observability from scratch and want alerting without assembling a separate component, SigNoz wins this round outright.


Decision Matrix: Pick Your Tool

Pick Jaeger if…

Pick SigNoz if…


The Honest Edge Cases

“Can I just use Jaeger now and migrate to SigNoz later?”

Sort of. Your instrumentation code doesn’t change, OTLP is OTLP. But your historical trace data in Jaeger’s storage doesn’t migrate to SigNoz’s ClickHouse. You’d start fresh on traces, which is usually fine since trace data has a TTL anyway.

“Does SigNoz replace Prometheus completely?”

It can for new services if you instrument with the OTel metrics SDK. For existing infrastructure (node exporters, postgres exporters, etc.), you’d configure SigNoz’s OTel Collector to scrape them. It’s workable, but if you have a mature Prometheus setup, you might find yourself running SigNoz alongside Prometheus rather than replacing it.

“What about Grafana + Tempo instead?”

Good question, Tempo is Grafana’s distributed tracing backend, and if you’re already deep in the Grafana ecosystem (Grafana dashboards, Loki, Mimir), Tempo is a natural fit. It’s more in the Jaeger category (tracing-focused) than the SigNoz category (all-in-one), but it integrates with Grafana’s exemplar-based correlation natively. Worth a look if you’re already running Grafana.

Also worth checking the SigNoz vs Uptrace comparison if you’re evaluating full-platform options, and OpenTelemetry for self-hosters for the instrumentation setup that ties all of this together.


The SumGuy Take

The choice is usually already made for you.

If you’ve got a running Prometheus + Grafana + Loki setup and you’ve been putting off adding tracing because it seemed complicated, add Jaeger. It’s a single Docker container for dev, it speaks OTLP natively in v2, and you’re off to the races in 20 minutes. Your existing observability stack stays intact. Jaeger does exactly one job and does it well.

If you’re standing up observability from scratch, have 8+ GB of RAM to spare on a dedicated host, and the idea of jumping between three UIs to debug a production incident sounds like exactly the kind of friction you don’t need, SigNoz is worth the setup cost. The correlation story is genuinely good, and not having to wire up alerting separately is a real quality-of-life win.

The mistake I see people make is picking SigNoz because it looks impressive, then running it on a 2-core 4GB VPS and wondering why ClickHouse is consuming everything. SigNoz is not a lightweight tool. Be honest about your hardware constraints before you commit.

And either way, instrument with OpenTelemetry. The fact that the same OTLPSpanExporter works with both is the ecosystem working as intended. You pick the backend to match your needs, not the other way around.

Your 2 AM self will appreciate having made this call before something breaks.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
ZFS Tuning for SSDs and NVMe
Next Post
Backup Workflow Patterns That Work

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts