What is a Micrometer MeterRegistry, and what role does it play in a Spring Boot application?
answer
- SLF4J for metrics
- factory + container of meters
- inject the interface, not the impl
- keyed by name + tags
- Boot auto-configures the bean
basics
~10 sMeterRegistry is Micrometer's central object that creates and holds meters (counters, gauges, timers). Spring Boot auto-configures one and injects it, so your code records metrics through it without knowing which monitoring backend receives them.
solid answer
~40 sMeterRegistry is the core interface in Micrometer — the metrics facade Spring Boot uses. It is a factory and a container: you call methods like registry.counter(...), Timer.builder(...).register(registry), or Gauge.builder(...) to create meters, and the registry tracks them. Each concrete registry is bound to one monitoring system (Prometheus, etc.) and knows how to publish there. Spring Boot auto-configures the appropriate registry from classpath starters and exposes it as a bean, so you just inject MeterRegistry and record data. Because your instrumentation talks only to the interface, the same code works regardless of which backend is configured — Micrometer is deliberately 'SLF4J for metrics'. Meters are cached by name plus tags, so repeated lookups return the same instrument rather than creating duplicates.
code
java · 24 linesimport io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final Counter ordersPlaced;
private final Timer checkoutTimer;
// Spring Boot injects the auto-configured MeterRegistry bean
public OrderService(MeterRegistry registry) {
this.ordersPlaced = registry.counter("orders.placed", "channel", "web");
this.checkoutTimer = Timer.builder("orders.checkout")
.description("time to complete checkout")
.register(registry);
}
public void checkout(Runnable work) {
checkoutTimer.record(work); // times the block
ordersPlaced.increment();
}
}go deeper
Know it's the object you inject to create counters/timers, and that Boot auto-configures it.
Explain the factory + container roles, name+tag caching, and the facade/SLF4J-for-metrics analogy.
Discuss the interface-vs-implementation split, the SimpleMeterRegistry fallback, and auto-instrumentation binding to the same registry.
Frame it as the seam that decouples instrumentation from backend, enabling backend swaps and multi-backend fan-out without touching call sites.
**Micrometer** is a vendor-neutral metrics instrumentation library — its tagline is 'SLF4J for application metrics.' Just as SLF4J lets you log without hard-coding Logback vs Log4j, Micrometer lets you record metrics without hard-coding Prometheus vs Datadog vs CloudWatch. **MeterRegistry** is the central interface of that library. It has two jobs: 1. **Factory** — it creates *meters*. A **meter** is the general term for a metric instrument. The common types are: **Counter** (a value that only increases, e.g. number of requests), **Gauge** (a value that goes up and down and is sampled on demand, e.g. queue size), **Timer** (records how long events take *and* how many there were), **DistributionSummary** (records the distribution of a value, e.g. payload sizes), **LongTaskTimer** (measures tasks still in progress), and **FunctionCounter/FunctionTimer** (track state held in another object). You create them via the registry: `registry.counter("orders.placed")`, or with builders like `Timer.builder("http.server.requests").register(registry)`. 2. **Container/registry** — it stores every meter created against it, keyed by the combination of **name + tags** (tags are key/value dimensions like `method=GET`). Asking for a meter with the same name and tags returns the *existing* one instead of creating a duplicate — so repeated calls in a hot path are cheap and consistent. **In Spring Boot**, the `spring-boot-starter-actuator` dependency plus a registry implementation (e.g. `micrometer-registry-prometheus`) triggers auto-configuration (`MetricsAutoConfiguration` and the per-system auto-configs) that creates a `MeterRegistry` **bean**. You obtain it by constructor injection: ```java @Service class OrderService { private final Counter placed; OrderService(MeterRegistry registry) { this.placed = registry.counter("orders.placed"); } } ``` Spring also auto-instruments a lot for you (HTTP server timings, JVM memory, GC, datasource pools) and binds them to that same registry. **Key facade point:** your code depends only on the `MeterRegistry` *interface*. The concrete class — `PrometheusMeterRegistry`, `SimpleMeterRegistry`, etc. — decides the naming conventions and how/when data is shipped to the backend. Swapping backends is a dependency change, not a code change. **Gotchas:** - If **no** registry implementation is on the classpath, Boot falls back to a `SimpleMeterRegistry` that only holds the latest values in memory (used by the `/actuator/metrics` endpoint) — nothing is exported anywhere. - The registry is thread-safe; you can safely cache a `Counter`/`Timer` reference in a field. - Meter creation is idempotent per name+tags, but *different* tag sets create *different* time series — watch cardinality.
- What happens if you inject MeterRegistry but have no registry implementation (like micrometer-registry-prometheus) on the classpath?Spring Boot supplies a SimpleMeterRegistry — an in-memory registry that keeps only the latest values and backs the /actuator/metrics endpoint. Nothing is exported to any external system; it is effectively a no-op for shipping data out.
- Why is calling registry.counter("orders.placed") twice safe?Meters are cached by name plus tag set. The second call returns the same Counter instance rather than creating a duplicate time series, so it is safe to look up in a hot path (though caching the reference is still slightly cheaper).
saying these in an interview costs you the question
- Thinking MeterRegistry itself talks to Prometheus/Datadog — it's the interface; the concrete registry does the exporting.
- Believing each registry.counter(...) call creates a new metric every time.
- Assuming metrics are exported even with no registry implementation on the classpath.