OpenTelemetry vs Micrometer
Choosing between OpenTelemetry and Micrometer for Spring Boot observability depends on your specific needs. This comparison covers their differences, strengths, and when to use each approach.
Executive Summary
Quick decision guide based on your requirements:
| Your Need | Recommended Choice | Why |
|---|---|---|
| Distributed tracing required | OpenTelemetry | Full W3C trace context support |
| Metrics only | Micrometer | Native Spring Boot integration, simpler setup |
| Multi-signal observability (traces + metrics + logs) | OpenTelemetry | Unified approach for all signals |
| Spring Boot monolith | Micrometer | Less overhead, native Spring support |
| Microservices architecture | OpenTelemetry | Better distributed tracing and context propagation |
| Vendor flexibility | OpenTelemetry | Any OTLP-compatible backend |
| Spring Actuator required | Micrometer | Built-in integration |
| Legacy Spring Boot 2.x | Micrometer | More mature, proven stability |
| Future-proofing | OpenTelemetry | Industry standard, growing adoption |
Bottom line: Use OpenTelemetry for distributed systems needing comprehensive observability. Use Micrometer for simpler applications focused on metrics. Both can coexist using Micrometer's OpenTelemetry bridge.
What is OpenTelemetry?
OpenTelemetry is a CNCF (Cloud Native Computing Foundation) project that provides a unified, vendor-neutral framework for collecting and exporting observability data. It covers three telemetry signals: traces, metrics, and logs.
Core characteristics:
Vendor-neutral - Works with any OTLP-compatible backend (Jaeger, Tempo, Prometheus, Uptrace, commercial APM tools). No vendor lock-in.
Multi-signal - Single framework for traces, metrics, and logs. Correlates all signals through shared context.
Distributed tracing - Built from the ground up for distributed systems. Full W3C Trace Context support enables tracing across services, clouds, and technologies.
Language-agnostic - Consistent API and behavior across Java, Python, Go, Node.js, and 20+ other languages.
Instrumentation options - Automatic instrumentation via Java Agent, manual instrumentation with API, or Spring Boot Starter for native integration.
OpenTelemetry emerged from the merger of OpenTracing and OpenCensus projects in 2019 and has become the industry standard for observability instrumentation.
What is Micrometer?
Micrometer is a metrics abstraction layer for JVM-based applications, serving as the de facto metrics library for Spring Boot. It provides a vendor-neutral API for collecting application metrics with support for multiple monitoring systems.
Core characteristics:
Metrics-focused - Designed specifically for dimensional metrics collection. Not a comprehensive observability solution.
Spring-native - Built into Spring Boot since version 2.0. Automatic configuration with Spring Boot Actuator provides metrics without additional setup.
Vendor abstraction - Supports 15+ monitoring systems (Prometheus, Datadog, New Relic, InfluxDB, etc.) through registry implementations.
Proven stability - Mature library used in production by thousands of Spring applications since 2017.
Simple API - Straightforward metrics recording with meters (counters, gauges, timers, distribution summaries).
Micrometer serves as the metrics layer for Spring applications, similar to how SLF4J serves as the logging facade.
Feature Comparison
Detailed comparison of capabilities:
| Feature | OpenTelemetry | Micrometer |
|---|---|---|
| Metrics Collection | ✅ Yes (OTLP metrics) | ✅ Yes (primary focus) |
| Distributed Tracing | ✅ Full W3C support | ⚠️ Limited via Micrometer Tracing |
| Log Collection | ✅ Yes (OTLP logs) | ❌ No |
| Correlation | ✅ Automatic (traces + metrics + logs) | ⚠️ Traces + metrics only |
| Backend Support | Any OTLP-compatible | 15+ via registries |
| Spring Boot Integration | Via Starter or Agent | Native (built-in) |
| Auto-instrumentation | ✅ Via Java Agent (150+ libraries) | ⚠️ Spring framework only |
| Manual Instrumentation | ✅ Rich API | ✅ Simple API |
| Context Propagation | ✅ Automatic across services | ⚠️ Manual configuration needed |
| Overhead | 2-5% CPU, 50-100MB RAM | <1% CPU, <20MB RAM |
| Standards Compliance | W3C, OTLP | None (custom) |
| Maturity | Stable (since 2021) | Very mature (since 2017) |
| Spring Boot Actuator | ⚠️ Via Micrometer bridge | ✅ Native integration |
| Learning Curve | Moderate | Low |
| Community Size | Growing (CNCF project) | Large (Spring ecosystem) |
OpenTelemetry Advantages
OpenTelemetry excels in these areas:
Full Distributed Tracing
OpenTelemetry provides complete distributed tracing with W3C Trace Context standard. Traces flow seamlessly across microservices, message queues, and async operations.
// Automatic trace propagation across services
@Service
public class OrderService {
private final RestTemplate restTemplate;
public Order createOrder(OrderRequest request) {
// Call to payment service - trace context propagates automatically
PaymentResponse payment = restTemplate.postForObject(
"http://payment-service/charge",
request,
PaymentResponse.class
);
// Both order and payment spans linked in same trace
return saveOrder(request, payment);
}
}
Micrometer Tracing provides basic tracing but requires more configuration and doesn't support advanced features like baggage propagation or complex sampling strategies.
Vendor-Agnostic Design
OpenTelemetry data exports to any OTLP-compatible backend. Switch observability vendors without changing application code.
# Change backend by updating configuration only
otel:
exporter:
otlp:
endpoint: https://new-backend:4318 # Switch vendors here
Micrometer requires changing registry dependencies and configuration when switching monitoring systems.
Multi-Signal Observability
Single instrumentation point captures traces, metrics, and logs with automatic correlation:
// One instrumentation, three signals
Span span = tracer.spanBuilder("process_order").startSpan();
try (Scope scope = span.makeCurrent()) {
// Traces
span.setAttribute("order.id", orderId);
// Metrics (automatically correlated via trace context)
ordersProcessed.add(1);
// Logs (include trace context automatically)
logger.info("Processing order {}", orderId);
} finally {
span.end();
}
Micrometer only handles metrics. You need separate libraries for logs and traces.
Future-Proof
OpenTelemetry is the CNCF standard for observability. Major vendors (AWS, Azure, Google Cloud, Datadog, New Relic) support OTLP natively. Adoption continues to grow across the industry.
Micrometer Advantages
Micrometer excels in these areas:
Native Spring Boot Integration
Micrometer ships with Spring Boot and requires zero configuration for basic metrics:
// Metrics work automatically with Spring Boot Actuator
@RestController
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
// HTTP metrics collected automatically
// - http.server.requests
// - request duration
// - status codes
return userService.findById(id);
}
}
No additional dependencies or configuration needed. Metrics appear at /actuator/metrics immediately.
Simpler Setup for Metrics
Recording custom metrics requires minimal code:
@Service
public class OrderService {
private final Counter ordersCreated;
public OrderService(MeterRegistry registry) {
this.ordersCreated = registry.counter("orders.created");
}
public void createOrder(Order order) {
processOrder(order);
ordersCreated.increment(); // Simple counter increment
}
}
OpenTelemetry requires more boilerplate for the same functionality.
Lower Overhead
Micrometer's metrics-only focus results in minimal resource usage:
- CPU overhead: <1% (vs 2-5% for OpenTelemetry)
- Memory overhead: <20MB (vs 50-100MB for OpenTelemetry)
- Network usage: Minimal (periodic metrics export vs continuous trace streaming)
For applications that only need metrics, Micrometer's lighter footprint is advantageous.
Proven Stability
Micrometer has been in production use since 2017 with millions of applications. Edge cases are well-understood and documented. Spring team provides long-term support.
Established Ecosystem
Spring Boot Actuator integration provides production-ready features:
- Health checks
- Application info
- Environment properties
- HTTP trace logs
- Thread dump
- Heap dump
All metrics integrate seamlessly with this ecosystem.
When to Use OpenTelemetry
Choose OpenTelemetry when you need:
Distributed tracing across microservices - Full trace context propagation between services, including async operations and message queues.
Multi-cloud or multi-vendor flexibility - Ability to switch observability backends without code changes.
Comprehensive observability - Unified collection of traces, metrics, and logs with automatic correlation.
Cross-platform systems - Applications using multiple programming languages (Java, Python, Go, Node.js) that need consistent instrumentation.
Advanced instrumentation - Automatic instrumentation of 150+ libraries via Java Agent, including databases, HTTP clients, and frameworks without code changes.
Future-proofing - Investment in the industry standard that major cloud providers and vendors support.
Example use case: E-commerce platform with Java order service, Python recommendation engine, Node.js API gateway, requiring end-to-end tracing and vendor-independent telemetry. For complete microservices monitoring patterns, see Spring Boot Microservices Monitoring.
When to Use Micrometer
Choose Micrometer when you need:
Metrics-only requirements - Application monitoring focused solely on metrics without distributed tracing needs.
Simple Spring Boot applications - Monolithic applications or small microservices where native Spring Boot integration is sufficient.
Minimal overhead - Resource-constrained environments where low CPU and memory usage is critical.
Spring Actuator dependency - Applications that rely on Spring Boot Actuator's production features.
Team familiarity - Teams already experienced with Micrometer and Spring Boot patterns.
Quick setup - Projects needing observability quickly without learning new frameworks.
Example use case: Internal admin dashboard (Spring Boot monolith) exposing metrics to Prometheus, using Spring Actuator health checks, with no distributed tracing requirements.
Integration Examples
Using OpenTelemetry in Spring Boot
Add dependencies:
<!-- Maven -->
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<version>2.20.1-alpha</version>
</dependency>
Configure in application.yml:
otel:
service:
name: order-service
traces:
exporter: otlp
metrics:
exporter: otlp
exporter:
otlp:
endpoint: http://localhost:4318
protocol: http/protobuf
Record custom metrics and traces:
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
@Service
public class OrderService {
private final Tracer tracer;
private final LongCounter ordersCounter;
public OrderService() {
this.tracer = GlobalOpenTelemetry.getTracer("orders");
this.ordersCounter = GlobalOpenTelemetry.getMeter("orders")
.counterBuilder("orders.created")
.build();
}
public Order createOrder(OrderRequest request) {
Span span = tracer.spanBuilder("create.order")
.setAttribute("customer.id", request.getCustomerId())
.startSpan();
try (var scope = span.makeCurrent()) {
Order order = processOrder(request);
ordersCounter.add(1);
return order;
} finally {
span.end();
}
}
}
See Spring Boot OpenTelemetry Integration for complete setup. For detailed manual instrumentation patterns, see OpenTelemetry Java Manual Instrumentation.
Using Micrometer in Spring Boot
Add dependencies (often already included):
<!-- Maven - usually already in spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Configure in application.yml:
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
export:
prometheus:
enabled: true
Record custom metrics:
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
@Service
public class OrderService {
private final Counter ordersCounter;
public OrderService(MeterRegistry registry) {
this.ordersCounter = registry.counter("orders.created");
}
public Order createOrder(OrderRequest request) {
Order order = processOrder(request);
ordersCounter.increment();
return order;
}
}
Using Both Together (Bridge Pattern)
Micrometer can bridge metrics to OpenTelemetry, allowing you to use Spring's native metrics while exporting via OTLP:
<!-- Add Micrometer OpenTelemetry bridge -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-otlp</artifactId>
</dependency>
Configuration:
management:
otlp:
metrics:
export:
url: http://localhost:4318/v1/metrics
step: 10s # Export interval
metrics:
export:
otlp:
enabled: true
This approach lets you:
- Keep existing Micrometer metrics code
- Use Spring Boot Actuator features
- Export metrics via OTLP to OpenTelemetry-compatible backends
- Add OpenTelemetry tracing separately if needed
Example:
@Service
public class OrderService {
private final Counter micrometerCounter; // Micrometer metric
private final Tracer otelTracer; // OpenTelemetry tracing
public OrderService(MeterRegistry registry) {
// Micrometer metric (exported via OTLP bridge)
this.micrometerCounter = registry.counter("orders.created");
// OpenTelemetry tracer
this.otelTracer = GlobalOpenTelemetry.getTracer("orders");
}
public Order createOrder(OrderRequest request) {
// OpenTelemetry trace
Span span = otelTracer.spanBuilder("create.order").startSpan();
try (var scope = span.makeCurrent()) {
Order order = processOrder(request);
// Micrometer metric (will be exported via OTLP)
micrometerCounter.increment();
return order;
} finally {
span.end();
}
}
}
This hybrid approach is common during migration or when you want Micrometer's simplicity for metrics with OpenTelemetry's tracing capabilities.
Migration Guide
From Micrometer to OpenTelemetry
If you're migrating from Micrometer to OpenTelemetry, follow this phased approach:
Phase 1: Add OpenTelemetry alongside Micrometer
Keep existing Micrometer metrics, add OpenTelemetry for tracing:
<!-- Keep existing Micrometer -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Add OpenTelemetry -->
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<version>2.20.1-alpha</version>
</dependency>
This allows both systems to coexist. Micrometer continues handling metrics while OpenTelemetry adds tracing.
Phase 2: Bridge Micrometer to OpenTelemetry
Export Micrometer metrics via OTLP:
management:
otlp:
metrics:
export:
url: http://localhost:4318/v1/metrics
metrics:
export:
otlp:
enabled: true
Now all metrics flow through OpenTelemetry collector. You can gradually migrate metrics code.
Phase 3: Migrate metrics to OpenTelemetry API
Convert Micrometer metrics to OpenTelemetry:
// Before (Micrometer)
private final Counter counter;
public OrderService(MeterRegistry registry) {
this.counter = registry.counter("orders.created",
Tags.of("region", "us-west"));
}
public void createOrder() {
counter.increment();
}
// After (OpenTelemetry)
private final LongCounter counter;
public OrderService() {
Meter meter = GlobalOpenTelemetry.getMeter("orders");
this.counter = meter.counterBuilder("orders.created").build();
}
public void createOrder() {
counter.add(1, Attributes.of(
AttributeKey.stringKey("region"), "us-west"
));
}
Migrate service by service over multiple releases.
Phase 4: Remove Micrometer dependency
Once all custom metrics are migrated:
<!-- Remove Micrometer -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency> -->
<!-- Keep OpenTelemetry -->
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<version>2.20.1-alpha</version>
</dependency>
Timeline: Plan 2-6 months for complete migration depending on application size.
Key Differences Summary
| Aspect | OpenTelemetry | Micrometer |
|---|---|---|
| Primary Purpose | Comprehensive observability (traces + metrics + logs) | Metrics collection and abstraction |
| Best For | Distributed microservices | Monolithic Spring applications |
| Learning Curve | Moderate (new concepts) | Low (familiar Spring patterns) |
| Setup Complexity | Higher (more configuration) | Lower (automatic with Spring Boot) |
| Flexibility | Very high (vendor-neutral OTLP) | High (15+ registries) |
| Performance Impact | 2-5% overhead | <1% overhead |
| Maturity | Stable, growing | Very mature |
| Industry Trend | Growing adoption | Established standard |
| Spring Integration | Via Starter or Agent | Native |
Key Takeaways
✓ OpenTelemetry provides comprehensive observability with traces, metrics, and logs for distributed systems.
✓ Micrometer offers simpler metrics collection with native Spring Boot integration for monolithic applications.
✓ Choose OpenTelemetry for microservices requiring distributed tracing and vendor flexibility.
✓ Choose Micrometer for metrics-only requirements with minimal overhead and Spring-native patterns.
✓ Both can coexist using Micrometer's OpenTelemetry bridge for hybrid approaches during migration.