Spring Boot Actuator Tutorial
Watch on YouTubeSpring Boot Actuator and Monitoring
What are Actuator and monitoring?
Monitoring means observing an application's health, performance, and
behavior. Spring Boot Actuator provides ready-made endpoints for this
purpose. These endpoints are different from business endpoints such as
/api/orders; they are operational endpoints for developers,
DevOps engineers, and platform systems.
For example, Kubernetes can call a health endpoint before sending users to a new application instance. Prometheus can read metrics, and Grafana can display them on a dashboard.
1. Add the Actuator dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Adding the starter creates Actuator endpoints, but most endpoints are not exposed over HTTP automatically. You must explicitly choose what should be available.
2. Health and readiness
Health answers whether an application can work correctly. A healthy response is useful for load balancers, containers, and operations teams.
GET /actuator/health
{
"status": "UP",
"components": {
"db": { "status": "UP" },
"diskSpace": { "status": "UP" }
}
}
Liveness vs readiness
- Liveness: The process is running. Restart it only when liveness fails.
- Readiness: The application is ready to receive traffic. Do not send traffic when readiness fails.
management.endpoint.health.probes.enabled=true
management.health.livenessstate.enabled=true
management.health.readinessstate.enabled=true
# Common Kubernetes URLs
GET /actuator/health/liveness
GET /actuator/health/readiness
A database outage may make readiness fail while the Java process is still alive. The platform can temporarily remove that instance from traffic instead of restarting it unnecessarily.
3. Application information
The info endpoint displays safe build and application
information. Do not put passwords, tokens, or private infrastructure
details here.
management.info.env.enabled=true
info.app.name=employee-service
info.app.version=1.4.0
info.app.environment=production
GET /actuator/info
4. Metrics
Metrics are numeric measurements collected over time. They help you see trends rather than investigating only after a failure.
GET /actuator/metrics
GET /actuator/metrics/jvm.memory.used
GET /actuator/metrics/http.server.requests
GET /actuator/metrics/system.cpu.usage
| Metric | What it tells you | Real use |
|---|---|---|
http.server.requests |
Request count, status, and timing | Find slow or failing endpoints |
jvm.memory.used |
Memory used by the JVM | Detect memory growth |
jdbc.connections.active |
Database connections in use | Find connection-pool pressure |
hikaricp.connections.pending |
Requests waiting for a connection | Detect database bottlenecks |
process.cpu.usage |
CPU used by the process | Decide when to scale |
5. Expose only required endpoints
Configure endpoint exposure in application.properties. The
include list adds endpoints; the exclude list
removes endpoints even when a broad include is used.
# Beginner/local setup
management.endpoints.web.exposure.include=health,info,metrics
# Production: expose a small, deliberate set
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoints.web.exposure.exclude=env,beans,configprops,threaddump
# Change the URL prefix if required
management.endpoints.web.base-path=/manage
With the custom base path, health is available at
/manage/health. Never assume an endpoint is private just
because its URL is difficult to guess.
6. Custom health indicators
Built-in health checks cover common dependencies. Add a custom indicator when your service depends on a payment gateway, warehouse API, message broker, or another business-critical system.
@Component("paymentGateway")
public class PaymentGatewayHealthIndicator
implements HealthIndicator {
private final PaymentGatewayClient client;
public PaymentGatewayHealthIndicator(PaymentGatewayClient client) {
this.client = client;
}
@Override
public Health health() {
try {
client.ping();
return Health.up()
.withDetail("provider", "ExamplePay")
.build();
} catch (Exception ex) {
return Health.down()
.withDetail("reason", "Payment gateway unavailable")
.build();
}
}
}
Use short timeouts in health checks. A health request should not hang because an external service is slow.
7. Add custom application information
@Component
public class DeploymentInfoContributor
implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("region", "ap-south-1")
.withDetail("service", "employee-service")
.withDetail("release", "2026.07.24");
}
}
8. Prometheus and Grafana
Prometheus periodically scrapes a metrics endpoint and stores the measurements. Grafana reads those measurements and displays charts and dashboards. Add Micrometer's Prometheus registry to publish metrics in Prometheus format.
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
management.endpoints.web.exposure.include=health,info,prometheus
GET /actuator/prometheus
Example Prometheus configuration:
scrape_configs:
- job_name: employee-service
metrics_path: /actuator/prometheus
static_configs:
- targets: ["employee-service:8080"]
9. View and change log levels
Actuator can show configured loggers and, when explicitly exposed, can temporarily change a logger level while diagnosing an issue.
management.endpoints.web.exposure.include=health,info,loggers,metrics
GET /actuator/loggers
GET /actuator/loggers/com.javacodeex.employee
POST /actuator/loggers/com.javacodeex.employee
Content-Type: application/json
{ "configuredLevel": "DEBUG" }
Protect this endpoint and return the level to its normal value after the investigation. Avoid enabling verbose logging for sensitive data.
10. Secure Actuator endpoints
Health may be public for a load balancer, but metrics, environment, and logging endpoints should normally require authentication and network restrictions.
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health/**").permitAll()
.requestMatchers("/actuator/**").hasRole("OPS")
.anyRequest().authenticated());
return http.build();
}
management.endpoint.health.show-details=when_authorized
Do not expose env, configprops, or
heapdump publicly. They may reveal configuration, memory
contents, or infrastructure details.
11. Create a custom Actuator endpoint
A custom endpoint is useful for safe operational information that is not part of the default Actuator set. Keep it read-only unless there is a strong operational reason to support write operations.
@Component
@Endpoint(id = "deployment")
public class DeploymentEndpoint {
@ReadOperation
public Map<String, String> deployment() {
return Map.of(
"version", "2026.07.24",
"region", "ap-south-1",
"commit", "abc123");
}
}
management.endpoints.web.exposure.include=health,info,deployment
GET /actuator/deployment
12. Real-world incident example
Suppose users report that checkout is slow. A simple investigation can follow this path:
-
Check
/actuator/health/readinessto confirm the instance can receive traffic. -
Check
http.server.requestsfor checkout latency and 5xx responses. - Check database connection metrics for active or pending connections.
- Check JVM memory and CPU to see whether the instance is overloaded.
- Use a protected logger endpoint temporarily if more application detail is needed.
- Fix the root cause, restore normal logging, and record the incident.
13. Container and Kubernetes usage
Containers use health probes to decide whether to restart an application or send traffic to it. Keep liveness checks lightweight and use readiness checks for dependencies that must be available before serving requests.
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
Best practices
- Expose only the endpoints your platform actually needs.
- Protect operational endpoints with authentication and network rules.
- Keep health checks fast and use timeouts for external dependencies.
- Use readiness for traffic decisions and liveness for restart decisions.
- Monitor latency, error rate, traffic, and resource saturation together.
- Never place secrets in the info endpoint or logs.
- Use Prometheus and Grafana or an equivalent monitoring platform in production.
Spring Boot Actuator FAQs
What is the difference between liveness and readiness?
Liveness indicates whether the process should be restarted. Readiness indicates whether the instance is prepared to receive traffic.
Should all Actuator endpoints be public?
No. Expose only required endpoints and protect them because they can reveal deployment, configuration, memory, or dependency details.
How are Actuator metrics exported to Prometheus?
Add the Micrometer Prometheus registry, expose the Prometheus endpoint, and configure Prometheus to scrape it over a protected network.
Next: DeploymentContinue learning
