Metrics & Service Monitoring
IntermediateThe RED method (Rate, Errors, Duration) and USE method (Utilisation, Saturation, Errors) provide service- and infrastructure-level metrics for dashboards and alerts.
Overview
Metrics are numerical measurements collected at regular intervals that reveal system health trends over time — different from logs (events) or traces (request flows). Two frameworks guide which metrics to collect: RED (Rate, Errors, Duration) targets service-level performance from a user perspective and is ideal for APIs and business logic; USE (Utilisation, Saturation, Errors) targets resource-level performance (CPU, memory, thread pools, database connections) from an infrastructure perspective. Prometheus + Grafana is the dominant stack: Prometheus scrapes metrics from service endpoints, stores time-series data, and evaluates alerting rules; Grafana visualises them as dashboards. Spring Boot Actuator with Micrometer exposes Prometheus-compatible metrics at /actuator/prometheus with zero custom code for common metrics.
RED and USE methods — what to measure
RED (Rate, Errors, Duration) answers: how busy is the service, how many requests fail, and how long do they take? Apply it to every service endpoint and downstream call. USE (Utilisation, Saturation, Errors) answers: what fraction of resources are in use, are resources queuing, and are hardware errors occurring? Apply it to CPUs, thread pools, connection pools, disk I/O.
# PromQL examples for RED metrics (Spring Boot / Micrometer)
# Rate: requests per second (5-min average)
rate(http_server_requests_seconds_count{job="order-service"}[5m])
# Error rate: 5xx errors as % of total requests
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/ sum(rate(http_server_requests_seconds_count[5m])) * 100
# Duration: P99 latency for POST /orders
histogram_quantile(0.99,
sum(rate(http_server_requests_seconds_bucket{
uri="/orders", method="POST"}[5m])) by (le))
# USE metrics (infrastructure)
# Utilisation: JVM thread pool active vs max
hikaricp_connections_active / hikaricp_connections_max
# Saturation: pending (queued) HikariCP connection requests
hikaricp_connections_pending
# JVM memory utilisation
jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}Spring Boot Micrometer + Prometheus setup
Spring Boot Actuator auto-configures Micrometer with counters, timers, and gauges for HTTP requests, JVM memory, GC pauses, thread pools, HikariCP connections, and Kafka consumer lag. Add the Prometheus registry dependency and expose the /actuator/prometheus endpoint for scraping.
<!-- pom.xml — add Prometheus registry -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
# application.yml — expose Prometheus endpoint
management:
endpoints:
web:
exposure:
include: health,info,prometheus,metrics
metrics:
distribution:
percentiles-histogram:
http.server.requests: true # enable histogram for quantile queries
percentiles:
http.server.requests: 0.5,0.95,0.99
tags:
application: ${spring.application.name} # tag all metrics with app name
environment: ${spring.profiles.active}
# Custom business metric example
@Service
public class OrderService {
private final Counter ordersPlaced;
public OrderService(MeterRegistry registry) {
ordersPlaced = Counter.builder("orders.placed")
.description("Total orders placed")
.tag("channel", "web")
.register(registry);
}
public Order placeOrder(OrderRequest req) {
Order order = processOrder(req);
ordersPlaced.increment();
return order;
}
}Alerting with Prometheus AlertManager
PrometheusRule resources define alerting conditions evaluated against the time-series database. Alerts fire when a condition holds for a specified duration (for). AlertManager routes fired alerts to PagerDuty, Slack, or email based on label matchers. Good alerts are actionable — they fire when a human needs to intervene, not for every transient spike.
# prometheus-rules.yml — alerting rules
groups:
- name: order-service
rules:
- alert: HighErrorRate
expr: |
sum(rate(http_server_requests_seconds_count{
job="order-service", status=~"5.."}[5m]))
/ sum(rate(http_server_requests_seconds_count{job="order-service"}[5m]))
> 0.05
for: 2m # must hold for 2 min to fire (avoids transient spikes)
labels:
severity: critical
team: platform
annotations:
summary: "High error rate on order-service"
description: "Error rate is {{ humanizePercentage $value }} (threshold: 5%)"
runbook: "https://wiki.example.com/runbooks/order-service-errors"
- alert: P99LatencyHigh
expr: |
histogram_quantile(0.99,
sum(rate(http_server_requests_seconds_bucket{
job="order-service"}[5m])) by (le))
> 2.0
for: 5m
labels:
severity: warning
annotations:
summary: "P99 latency above 2s on order-service"Key Points to Remember
- 1RED method (Rate, Errors, Duration) measures service-level performance from user perspective — apply to every API endpoint
- 2USE method (Utilisation, Saturation, Errors) measures resource-level performance — apply to CPU, thread pools, connection pools
- 3Spring Boot Actuator + micrometer-registry-prometheus auto-instruments HTTP, JVM, HikariCP, and Kafka metrics at zero cost
- 4Enable percentiles-histogram in application.yml to allow PromQL histogram_quantile() for accurate P50/P95/P99 queries
- 5Tag all metrics with application name and environment — this enables dashboard filtering and multi-service comparison
- 6Alerts should have for: duration to avoid transient spike noise, and runbook links for on-call engineers
Interview Questions
Sign in to ask AriaWhat are the RED and USE methods and which one would you use for API performance monitoring?
How does Spring Boot expose Prometheus metrics and what auto-instrumented metrics are available?
Write a PromQL expression to calculate the P99 latency of POST /orders over the last 5 minutes.
Why should Prometheus alerting rules use the for clause and what happens without it?
How would you instrument a business metric (e.g. orders placed per second) in a Spring Boot service?
Ask Aria about Metrics & Service Monitoring
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.