Spring Boot
Micrometer
Service Performance
Monitoring
Java Development

How to measure service methods using spring boot 2 and micrometer

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Spring Boot 2 uses Micrometer as its metrics facade, which makes it straightforward to measure service-layer performance without committing to a single monitoring backend. For method-level timing, the most common approaches are @Timed for declarative timing and Timer for explicit code-driven measurements.

Add the Required Dependencies

At minimum, you usually want Spring Boot Actuator so metrics are exposed, plus the registry for your backend. Prometheus is a common example.

xml
1<dependency>
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-actuator</artifactId>
4</dependency>
5
6<dependency>
7    <groupId>io.micrometer</groupId>
8    <artifactId>micrometer-registry-prometheus</artifactId>
9</dependency>

Then expose the metrics endpoints:

properties
management.endpoints.web.exposure.include=health,info,metrics,prometheus
management.metrics.tags.application=orders-service

Without Actuator exposure, the code may record metrics correctly but nothing will be visible from the outside.

Time a Service Method with @Timed

The simplest option is to annotate the service method.

java
1import io.micrometer.core.annotation.Timed;
2import org.springframework.stereotype.Service;
3
4@Service
5public class BillingService {
6
7    @Timed(value = "billing.charge.time", description = "Time spent charging a customer")
8    public String charge(String customerId) {
9        try {
10            Thread.sleep(120);
11        } catch (InterruptedException e) {
12            Thread.currentThread().interrupt();
13        }
14        return "charged-" + customerId;
15    }
16}

This records timing data for every invocation. In many projects, that is enough for service methods where you want latency and invocation count but do not need custom tags.

If @Timed does not produce data, check that timed aspect support is enabled. Depending on your setup, adding AOP support is the missing step.

xml
1<dependency>
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-aop</artifactId>
4</dependency>

Use Timer for More Control

Programmatic timers are a better fit when you want dynamic tags or when only part of the method should be measured.

java
1import io.micrometer.core.instrument.MeterRegistry;
2import io.micrometer.core.instrument.Timer;
3import org.springframework.stereotype.Service;
4
5@Service
6public class ReportService {
7
8    private final MeterRegistry meterRegistry;
9
10    public ReportService(MeterRegistry meterRegistry) {
11        this.meterRegistry = meterRegistry;
12    }
13
14    public String buildReport(String type) {
15        Timer.Sample sample = Timer.start(meterRegistry);
16        try {
17            Thread.sleep("full".equals(type) ? 180 : 60);
18            return "report-" + type;
19        } catch (InterruptedException e) {
20            Thread.currentThread().interrupt();
21            throw new IllegalStateException("report generation interrupted", e);
22        } finally {
23            sample.stop(
24                Timer.builder("report.build.time")
25                    .description("Time spent building reports")
26                    .tag("type", type)
27                    .register(meterRegistry)
28            );
29        }
30    }
31}

This pattern is especially useful when you want tags such as report type, tenant, or region. It also gives you precise control over the measured code region.

Inspect the Recorded Metrics

Once the application is running, Spring Boot exposes metrics such as:

  • '/actuator/metrics'
  • '/actuator/metrics/billing.charge.time'
  • '/actuator/prometheus'

For Prometheus, you scrape /actuator/prometheus and then build dashboards in Grafana or another visualization tool. Timers commonly emit count, total time, and max. Depending on the registry, you may also configure percentiles or histogram buckets.

What to Measure at the Service Layer

Service methods are a useful boundary because they often correspond to business operations such as charging an order, generating an invoice, or loading customer history. That makes service metrics easier to interpret than very low-level helper timings.

Still, do not instrument everything indiscriminately. Too many high-cardinality tags can make your metric system expensive and noisy. Measure stable business operations, attach low-cardinality tags, and use logs or tracing for request-specific detail.

Common Pitfalls

  • Expecting @Timed to work without the supporting AOP setup causes confusion. If the annotation is present but no metric appears, verify that the aspect path is enabled.
  • Using highly variable tag values such as user IDs creates cardinality problems. Prefer stable tags such as operation name, result, or report type.
  • Measuring only controller methods can hide slow service logic shared by multiple endpoints. Put the timer at the layer where the business work actually happens.
  • Forgetting to expose Actuator endpoints makes it seem like metrics are missing. Recording and exporting are separate concerns.
  • Timing extremely small helper methods adds noise with little operational value. Focus on service operations that matter to users or downstream systems.

Summary

  • Spring Boot 2 integrates Micrometer for vendor-neutral application metrics.
  • '@Timed is the fastest way to add service-method latency measurement.'
  • 'Timer and Timer.Sample give you more control over tags and measured regions.'
  • Actuator endpoints and a registry backend are required to inspect or scrape the metrics.
  • Good service metrics use stable names and low-cardinality tags so dashboards stay useful.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.