Skip to content

OpenTelemetry vs Micrometer for Spring Boot: Which Should You Use?

The Confusion

I needed to add monitoring to my Spring Boot microservices. Simple enough, right? I started researching and quickly got overwhelmed. Half the blog posts mentioned Micrometer, the other half talked about OpenTelemetry. Some said to use both. Which one should I pick? Were they competing tools or complementary ones?

I spent a weekend going down rabbit holes, trying different setups, and eventually figuring out the real story. Here’s what I learned through trial and error.

My First Attempt: Micrometer

I started with Micrometer because it’s built into Spring Boot. Spring Boot Actuator exposes metrics automatically, and Micrometer provides the facade to send those metrics to different backends.

The setup was embarrassingly simple.

I added this to my build.gradle:

build.gradle
implementation 'io.micrometer:micrometer-registry-prometheus'

Then enabled the Prometheus endpoint in my configuration:

application.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}

That’s it. My application now exposed a /actuator/prometheus endpoint that Prometheus could scrape. I could see JVM metrics, HTTP request counts, and database connection pool stats without writing a single line of custom code.

But I had a problem. I was building microservices, and when a request flowed through three different services, I couldn’t trace it end-to-end. Micrometer gave me metrics, but not distributed tracing.

My Second Attempt: OpenTelemetry

I needed traces. So I looked at OpenTelemetry, which promises unified metrics, logs, and traces in a single framework.

The setup was more involved.

I added the OpenTelemetry Spring Boot starter:

build.gradle
implementation("io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter")

Then configured where to send the telemetry data:

application.yml
otel:
exporter:
otlp:
endpoint: http://localhost:4317
traces:
exporter: otlp
metrics:
exporter: otlp
logs:
exporter: otlp

Now I needed an OpenTelemetry Collector to receive the data and a backend to store it. I set up a quick Docker Compose stack with the collector and ClickHouse:

docker-compose.yml
version: '3.8'
services:
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317"
- "4318:4318"
clickhouse:
image: clickhouse/clickhouse-server:latest
ports:
- "8123:8123"
- "9000:9000"

The collector configuration routed telemetry to ClickHouse:

otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
clickhouse:
endpoint: tcp://clickhouse:9000
database: otel
ttl: 72h
traces_table_name: otel_traces
metrics_table_name: otel_metrics
logs_table_name: otel_logs
service:
pipelines:
traces:
receivers: [otlp]
exporters: [clickhouse]
metrics:
receivers: [otlp]
exporters: [clickhouse]
logs:
receivers: [otlp]
exporters: [clickhouse]

This worked. I now had traces flowing through my services, metrics in ClickHouse, and logs all in one place. The OpenTelemetry default schema even gave me useful dashboards out of the box.

But I realized something: the setup complexity was significantly higher than Micrometer. I had to manage a collector, configure pipelines, and maintain ClickHouse.

The Realization: Different Tools for Different Needs

After going back and forth, I realized these tools serve different purposes:

Micrometer is a metrics facade. It’s focused on one thing: collecting and exporting application metrics. It integrates natively with Spring Boot Actuator and supports multiple backends (Prometheus, Datadog, Dynatrace, etc.).

OpenTelemetry is a comprehensive observability framework. It handles metrics, logs, and traces together. It’s vendor-neutral, future-proof, and requires more infrastructure.

Here’s how they compare:

AspectOpenTelemetryMicrometer
ScopeMetrics, Logs, Traces (unified)Metrics only
Spring Boot IntegrationSpring Boot Starter (autoconfiguration)Native Actuator support
Setup ComplexityModerate (requires collector/backend)Low (Spring Boot default)
Vendor Lock-inNone - open standardLow - multiple backend support
Automatic InstrumentationYes (Java agent or starter)Limited (requires manual instrumentation)
Learning CurveSteeper (three pillars)Gentle (metrics-focused)
Best ForFull observability stackMetrics-first approach

When I’d Use OpenTelemetry

I’d choose OpenTelemetry when:

I need distributed tracing. If I’m debugging requests that span multiple microservices, traces are essential. OpenTelemetry gives me traces with correlation to metrics and logs.

I want unified telemetry. Having metrics, logs, and traces in one pipeline means I can correlate issues across all three signals. When latency spikes in my metrics, I can jump to traces to see which service is slow, then check logs for errors.

I’m in a cloud-native environment. OpenTelemetry works well with Kubernetes operators, service meshes like Istio, and provides vendor-neutral portability across clouds.

I’m thinking long-term. OpenTelemetry is a CNCF graduated project with strong industry momentum. It’s becoming the standard for observability.

When I’d Use Micrometer

I’d choose Micrometer when:

I just need metrics. If my application is relatively simple or I’m not running distributed microservices, Micrometer gives me everything I need with minimal setup.

I want quick time-to-value. Micrometer with Prometheus and Grafana is a proven, straightforward stack. I can get meaningful monitoring in minutes.

I’m already invested in Spring. Micrometer is the native choice for Spring Boot. It feels natural to Spring developers and integrates seamlessly with Spring Cloud.

I have an existing Prometheus stack. Micrometer’s Prometheus support is first-class. The scrape-based architecture is simple and battle-tested.

The Hybrid Approach

Here’s what surprised me: I can use both.

In my production setup, I ended up using Micrometer for custom business metrics and OpenTelemetry for traces and infrastructure metrics.

Micrometer for custom metrics:

OrderService.java
import io.micrometer.core.instrument.*;
import org.springframework.stereotype.Service;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class OrderService {
private final Counter orderCounter;
private final Timer orderProcessingTime;
private final AtomicLong activeOrders = new AtomicLong(0);
public OrderService(MeterRegistry registry) {
this.orderCounter = Counter.builder("orders.created")
.tag("service", "order")
.description("Total orders created")
.register(registry);
this.orderProcessingTime = Timer.builder("orders.processing.time")
.tag("service", "order")
.publishPercentiles(0.95, 0.99)
.register(registry);
Gauge.builder("orders.active", activeOrders, AtomicLong::get)
.tag("service", "order")
.description("Currently active orders")
.register(registry);
}
public Order createOrder(OrderRequest request) {
return orderProcessingTime.record(() -> {
Order order = processOrder(request);
orderCounter.increment();
activeOrders.incrementAndGet();
return order;
});
}
}

OpenTelemetry for traces:

The OpenTelemetry Spring Boot starter automatically instruments HTTP requests, database calls, and other common operations. I get distributed tracing without writing code.

Bridge them together:

To send Micrometer metrics through OpenTelemetry’s pipeline, I added the OTLP registry:

build.gradle
implementation 'io.micrometer:micrometer-registry-otlp'
application.yml
management:
otlp:
metrics:
export:
url: http://localhost:4318/v1/metrics
step: 1m

Now my Micrometer metrics flow through the OpenTelemetry collector to ClickHouse, alongside my traces and logs.

Architecture Comparison

Here’s how each approach looks architecturally:

OpenTelemetry Architecture:

┌─────────────────┐
│ Spring Boot │
│ + OTel Starter │
└────────┬────────┘
│ OTLP
┌─────────────────┐
│ OTel Collector │
└────────┬────────┘
┌────┴────┬──────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌──────────┐
│Traces │ │Metrics│ │ Logs │
└───┬───┘ └───┬───┘ └────┬─────┘
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌──────────┐
│Jaeger │ │Click │ │ HyperDX │
│ │ │House │ │ │
└───────┘ └───────┘ └──────────┘

Micrometer Architecture:

┌─────────────────┐
│ Spring Boot │
│ + Actuator │
│ + Micrometer │
└────────┬────────┘
┌─────────────────┐
│ MeterRegistry │
└────────┬────────┘
┌────┴────┬──────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌──────────┐
│Prometh│ │Datadog│ │ Dynatrace│
│ eus │ │ │ │ │
└───────┘ └───────┘ └──────────┘

Decision Framework

After all my experiments, here’s my decision tree:

Choose OpenTelemetry if:

  • You need distributed tracing for microservices
  • You want unified metrics, logs, and traces in one pipeline
  • You’re in a cloud-native architecture (Kubernetes, service mesh)
  • You want a future-proof, vendor-neutral solution
  • You’re willing to invest in collector/backend setup

Choose Micrometer if:

  • Metrics are your primary concern
  • You want quick setup with Spring Boot Actuator
  • You have an existing Prometheus/Grafana stack
  • Your team is familiar with the Spring ecosystem
  • You prefer lower initial complexity

Consider the hybrid approach if:

  • You’re already using Micrometer for metrics
  • You want to add tracing incrementally
  • You need a migration path to full OpenTelemetry
  • You want gradual observability maturity

What Worked Best for Me

I ended up with the hybrid approach. My custom business metrics (orders processed, payment failures, user registrations) come from Micrometer because the API is clean and Spring-native. My distributed traces and infrastructure metrics come from OpenTelemetry because I get automatic instrumentation and unified correlation.

The combination gives me the best of both worlds: Micrometer’s simplicity for business metrics, and OpenTelemetry’s comprehensiveness for distributed tracing.

Summary

In this post, I walked through my journey of choosing between OpenTelemetry and Micrometer for Spring Boot monitoring. I started with Micrometer because of its simplicity and native Spring Boot integration, then explored OpenTelemetry for unified observability across metrics, logs, and traces. I discovered they serve different purposes: Micrometer excels as a focused metrics facade with minimal setup, while OpenTelemetry provides comprehensive observability with more infrastructure requirements. Finally, I found that a hybrid approach using both tools gave me the best combination of simplicity and observability power.

The choice depends on your specific needs. Start with Micrometer if you need metrics quickly with minimal overhead. Choose OpenTelemetry if you need distributed tracing and unified telemetry. Or combine both using Micrometer’s OTLP registry for a pragmatic middle ground.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments