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:
implementation 'io.micrometer:micrometer-registry-prometheus'Then enabled the Prometheus endpoint in my configuration:
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:
implementation("io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter")Then configured where to send the telemetry data:
otel: exporter: otlp: endpoint: http://localhost:4317 traces: exporter: otlp metrics: exporter: otlp logs: exporter: otlpNow 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:
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:
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:
| Aspect | OpenTelemetry | Micrometer |
|---|---|---|
| Scope | Metrics, Logs, Traces (unified) | Metrics only |
| Spring Boot Integration | Spring Boot Starter (autoconfiguration) | Native Actuator support |
| Setup Complexity | Moderate (requires collector/backend) | Low (Spring Boot default) |
| Vendor Lock-in | None - open standard | Low - multiple backend support |
| Automatic Instrumentation | Yes (Java agent or starter) | Limited (requires manual instrumentation) |
| Learning Curve | Steeper (three pillars) | Gentle (metrics-focused) |
| Best For | Full observability stack | Metrics-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:
import io.micrometer.core.instrument.*;import org.springframework.stereotype.Service;import java.util.concurrent.atomic.AtomicLong;
@Servicepublic 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:
implementation 'io.micrometer:micrometer-registry-otlp'management: otlp: metrics: export: url: http://localhost:4318/v1/metrics step: 1mNow 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:
- 👨💻 OpenTelemetry Java Documentation
- 👨💻 OpenTelemetry Spring Boot Starter
- 👨💻 Micrometer Documentation
- 👨💻 Spring Boot Actuator
- 👨💻 OpenTelemetry Collector Configuration
- 👨💻 ClickHouse OpenTelemetry Integration
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments