Spring BootActuatorintermediate
Updated:

Spring Boot Actuator Interview Questions and Answers

7 min read

Spring Boot Actuator interview questions answered — endpoints, health groups, liveness and readiness probes, custom health indicators, Prometheus metrics and securing it all.

TL;DR – Quick Answer

Spring Boot Actuator adds production-ready endpoints for health, metrics, environment, loggers and diagnostics over HTTP or JMX. Interviews test whether you can expose endpoints safely, wire liveness and readiness probes for Kubernetes, write a custom HealthIndicator, publish Micrometer metrics to Prometheus, and secure the whole surface. The recurring theme is operating a service, not just building it.

On This Page

Actuator is where Spring Boot meets operations. Interviewers reach for it to find out whether you've run a service in production or only written one — because health checks, readiness probes, metrics and the security of the management surface are things you only learn by deploying. The questions below track how a real service is monitored, from the health endpoint a load balancer polls to the Prometheus scrape a dashboard reads.

What is Actuator and what does it give you out of the box?

Actuator is a Spring Boot module that adds production-ready operational endpoints — health, info, metrics, env, loggers, threaddump, heapdump, beans, mappings and more — over HTTP (or JMX). Add spring-boot-starter-actuator and they light up under /actuator, giving you monitoring and management without writing any of it.

The value is that these are standardized. Every Actuator-enabled service exposes health at the same path, metrics in the same shape, loggers with the same controls — so your monitoring, load balancers and orchestration can treat services uniformly. That standardization is the whole point: operability by convention.

Interview note: Trap: "does adding the actuator starter expose everything?" No — by default only health is exposed over the web (and info if populated). All other endpoints exist but are not web-exposed until you opt them in. Assuming everything is public out of the box is a common and revealing mistake.

How do you expose additional endpoints, and why isn't that the default?

Set management.endpoints.web.exposure.include. It isn't the default because most endpoints leak sensitive data — env shows configuration, heapdump dumps memory, loggers lets a caller change log levels at runtime. Exposure is opt-in so you don't accidentally publish your internals.

You list the endpoints you want, or * for all (which you should reserve for a secured internal port). The corollary property management.endpoints.web.exposure.exclude subtracts from the set. Being explicit here is a security posture, not a formality.

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus,loggers
  endpoint:
    health:
      show-details: when-authorized   # hide health internals from anonymous callers

Interview note: Follow-up: "why set show-details: when-authorized rather than always?" Because the detailed health response lists your dependencies and their status — a map of what to attack. when-authorized shows the aggregated status to everyone but the component breakdown only to authenticated callers.

How do the health endpoint and its status work?

/actuator/health aggregates every registered HealthIndicator into one overall status — UP, DOWN, OUT_OF_SERVICE or UNKNOWN — and returns HTTP 200 for UP and 503 for DOWN. Built-in indicators cover the datasource, disk space, and other detected dependencies.

The aggregation rule is what interviewers probe: the overall status is the worst of the parts, so one DOWN dependency takes the whole endpoint DOWN. That's why a load balancer polling /actuator/health will pull a pod out of rotation when its database is unreachable — the behavior you want, but only if you understand that a single indicator can flip the whole service.

Interview note: Trap: "your health endpoint returns DOWN because a non-critical cache is unreachable, and traffic gets cut off — how do you fix that?" Don't let a non-critical dependency contribute to the readiness group. Use health groups to include only the indicators that should gate traffic, and leave optional dependencies out of the group the load balancer polls.

How do you wire liveness and readiness probes for Kubernetes?

Actuator exposes two built-in health groups — liveness and readiness — at /actuator/health/liveness and /actuator/health/readiness. Liveness means "the app is not in a broken state; restarting won't help unless it's down"; readiness means "the app can serve traffic right now." You point Kubernetes' livenessProbe and readinessProbe at those paths.

The distinction is operationally critical. A failing liveness probe tells Kubernetes to restart the pod; a failing readiness probe tells it to stop routing traffic without restarting. Getting them backwards is a classic outage: if you point the liveness probe at readiness, a temporary dependency blip triggers a pod restart instead of a brief traffic pause. Spring Boot auto-detects a Kubernetes environment and enables these groups; you can also force them on.

management:
  endpoint:
    health:
      probes:
        enabled: true
      group:
        readiness:
          include: readinessState,db   # gate traffic on the DB, not the cache

Interview note: Follow-up: "what makes readiness flip to down during startup and shutdown?" Spring publishes AvailabilityChangeEvents: readiness is REFUSING_TRAFFIC until the context is fully started, and flips back during graceful shutdown so the app drains in-flight requests while new traffic is routed elsewhere.

How do you write a custom HealthIndicator?

Implement the HealthIndicator interface (or extend AbstractHealthIndicator) as a @Component, and return Health.up() or Health.down() with optional details. Its status is automatically folded into /actuator/health and can be added to a health group.

Custom indicators exist for the dependencies Spring can't detect — a partner API, a message broker, a licensing service. The bean name becomes the key in the health response (a PaymentGatewayHealthIndicator shows up under paymentGateway). Keep the check fast and cheap, because it may be polled every few seconds by a load balancer.

@Component
public class PaymentGatewayHealthIndicator implements HealthIndicator {
    private final GatewayClient client;

    public PaymentGatewayHealthIndicator(GatewayClient client) {
        this.client = client;
    }

    @Override
    public Health health() {
        try {
            client.ping();
            return Health.up().withDetail("latencyMs", client.lastLatency()).build();
        } catch (Exception e) {
            return Health.down(e).build();
        }
    }
}

Interview note: Trap: "your custom indicator does a 5-second network call and the health endpoint now times out — what's wrong?" A health check that's slow or heavy becomes its own outage under frequent polling. Give it a short timeout, cache the result briefly, or move an expensive dependency check out of the readiness group.

How does Actuator produce metrics, and how do you get them into Prometheus?

Metrics go through Micrometer, a vendor-neutral metrics facade. Actuator auto-instruments HTTP request timings, JVM memory and GC, HikariCP pool usage and more; you read them at /actuator/metrics. Add micrometer-registry-prometheus and expose the prometheus endpoint, and the same metrics are published in Prometheus scrape format at /actuator/prometheus.

The design point worth stating: Micrometer is to metrics what SLF4J is to logging — you instrument once against Micrometer's Counter, Timer and Gauge, and swap the registry to target Prometheus, or another backend, without touching instrumentation. That decoupling is why interviewers like the Prometheus question: it checks you know Micrometer is the layer, not Prometheus.

@Service
public class OrderService {
    private final Counter placedOrders;

    public OrderService(MeterRegistry registry) {
        this.placedOrders = registry.counter("orders.placed");
    }

    public void place(Order o) {
        // ... business logic ...
        placedOrders.increment();
    }
}

Interview note: Follow-up: "how would you measure the latency of that method?" Wrap it in a Micrometer Timer or annotate it @Timed (with TimedAspect enabled). Timers give you count, total time and percentiles, which is what you actually chart — not just a raw counter.

How do you build a custom Actuator endpoint?

Annotate a @Component with @Endpoint(id = "...") and add @ReadOperation, @WriteOperation or @DeleteOperation methods. Spring exposes it under /actuator/<id> and honors the same exposure and security rules as the built-in endpoints.

You reach for this when a built-in endpoint doesn't cover an operational need — a controlled cache flush, a feature-flag toggle, a snapshot of an internal queue. Unlike a regular @RestController, a custom endpoint participates in Actuator's exposure/security model and is available over both HTTP and JMX, which is exactly why you'd use it instead of a plain controller for operational actions.

@Component
@Endpoint(id = "cachestats")
public class CacheStatsEndpoint {
    private final CacheManager cacheManager;

    public CacheStatsEndpoint(CacheManager cm) { this.cacheManager = cm; }

    @ReadOperation
    public Map<String, Integer> stats() {
        return cacheManager.getCacheNames().stream()
            .collect(Collectors.toMap(n -> n, n -> sizeOf(n)));
    }
}

Interview note: Trap: "why not just expose this as a normal REST controller?" A controller sits in your public API surface with its own security and shows up in your app's routing. A custom endpoint lives under /actuator, inherits management-port isolation and exposure control, and is clearly an operational tool — separation that matters for both security and clarity.

How do you secure the Actuator surface in production?

Three layers, used together: expose only the endpoints you need; protect sensitive ones with Spring Security (require an admin role on /actuator/** beyond health); and optionally move the entire management surface to a separate port with management.server.port bound to an internal network.

The separate-port move is the strongest isolation: application traffic hits 8080, operational traffic hits, say, 8081 reachable only from inside the cluster, so Actuator is never on the public listener at all. Combine it with management.endpoints.web.base-path to change the /actuator prefix if you want to reduce drive-by scanning. The point interviewers want: Actuator is powerful enough to be dangerous, so treat it as privileged.

management:
  server:
    port: 8081        # management on a separate, internal-only port
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus

Interview note: Follow-up: "if Actuator is on an internal-only port, do you still need Spring Security on it?" Defense in depth says yes — network isolation can fail or be misconfigured, so securing the endpoints and isolating the port are complementary, not alternatives.

What interviewers really test

Actuator questions are an operations proxy. The interviewer is checking whether you've had a pod restart-looping because liveness was pointed at readiness, whether you've watched a service get pulled from rotation by one DOWN indicator, whether you've ever accidentally exposed env and learned why that's frightening. Concrete operational reasoning beats endpoint-listing every time.

Ground the mechanics through the Spring Boot learning path, then connect Actuator to the systems it feeds: it's the backbone of health and metrics in a Spring Cloud setup, and its exposure is driven by the same externalized settings covered in configuration properties. When you can walk a request from "load balancer polls readiness" to "Prometheus scrapes the timer you added" without pausing, an Actuator-focused mock interview turns into a conversation about systems you've actually run.

Frequently Asked Questions

What is Spring Boot Actuator used for?
It exposes operational endpoints — health, metrics, env, loggers, thread and heap dumps — so you can monitor and manage a running application. It's the standard way to make a Spring Boot service observable and to feed health checks to load balancers and orchestrators like Kubernetes.
Why is only /actuator/health exposed by default?
Because the other endpoints reveal sensitive information — env leaks configuration, heapdump leaks memory contents, loggers let callers change log levels. Spring Boot exposes health (and info) over the web by default and requires you to opt every other endpoint in via management.endpoints.web.exposure.include, on purpose.
How do liveness and readiness probes differ in Spring Boot?
Liveness answers 'is the app broken and needing a restart?'; readiness answers 'can the app accept traffic right now?'. Actuator exposes them as health groups at /actuator/health/liveness and /actuator/health/readiness, which map directly to Kubernetes livenessProbe and readinessProbe.
How does Actuator expose metrics to Prometheus?
Through Micrometer. Add the micrometer-registry-prometheus dependency and expose the prometheus endpoint, and Actuator publishes metrics in Prometheus format at /actuator/prometheus for scraping. Micrometer is a vendor-neutral facade, so the same instrumentation can target other backends.
How do you secure Actuator endpoints?
Expose only what you need, protect the sensitive endpoints with Spring Security (for example requiring an admin role), or move the whole management surface to a separate internal-only port with management.server.port. Never expose the full /actuator/** publicly on the internet.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Java Full Stack program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us