Skip to main content

Health Checks

Health checks allow the circuit breaker to monitor service health and manage state transitions automatically.

info

Only the leader instance runs health checks. Follower instances wait for state updates from the leader. This prevents duplicate health checks and reduces load on the protected service.

Recovery Health Checks

When the circuit opens due to failures, the leader instance automatically begins recovery health checks.

Behavior

  • Trigger: Starts automatically when the circuit transitions to OPEN state
  • Timing: Uses the configured backoff strategy (e.g., exponential backoff)
  • Purpose: Determine when the service has recovered
  • Result: Circuit closes when a health check succeeds

Backoff Strategy

Recovery health checks use a backoff strategy to control retry timing. See the Backoff Strategies guide for available options.

import { CircuitBreaker, ExponentialBackoff } from "zenvark";

const circuitBreaker = new CircuitBreaker({
health: {
// Start with 1s delay, double after each failure, max 30s
backoff: new ExponentialBackoff({
initialDelayMs: 1000,
multiplier: 2,
maxDelayMs: 30_000,
}),
async check(type: HealthCheckType, signal: AbortSignal) {
await fetch("https://api.example.com/health", { signal });
},
},
});

Idle Health Checks

Idle health checks are optional and provide proactive monitoring when the circuit is closed but inactive. They detect service degradation before the next request arrives.

How It Works

Consider a circuit breaker with idleProbeIntervalMs: 10000 (10 seconds):

TimeEventDescription
0sCircuit breaker startsWaiting for first activity
5sCall executedIdle timer starts (10s countdown)
15sIdle Probe #1First health check runs (10s after call)
25sIdle Probe #2Second health check runs (10s after previous probe)
30sCall executedTimer cancelled and restarted
40sIdle Probe #3Health check resumes (10s after call at 30s)

Key points:

  • The first probe runs after the circuit breaker starts or after the last call completes (not immediately)
  • Subsequent probes run at fixed intervals while the circuit stays idle
  • A new call interrupts the idle timer and restarts it from zero
  • If a health check fails, the circuit opens immediately

Enabling Idle Health Checks

Enable idle health checks by setting the idleProbeIntervalMs option:

const circuitBreaker = new CircuitBreaker({
health: {
backoff: new ConstantBackoff({ delayMs: 5000 }),
async check(type: HealthCheckType, signal: AbortSignal) {
await fetch("https://api.example.com/health", { signal });
},
idleProbeIntervalMs: 30_000, // Check every 30 seconds when idle
},
});

Handling AbortSignal and Timeouts

The signal parameter in health checks allows Zenvark to cancel ongoing health checks when needed (e.g., when the circuit breaker stops). Always pass it to async operations:

import { HealthCheckType } from "zenvark";

// ✅ Good: Signal passed to fetch
async check(type: HealthCheckType, signal: AbortSignal) {
const response = await fetch("https://api.example.com/health", { signal });
if (!response.ok) {
throw new Error(`Health check failed: ${response.status}`);
}
}

// ❌ Bad: Signal ignored
async check(type: HealthCheckType, signal: AbortSignal) {
const response = await fetch("https://api.example.com/health");
// Health check won't be cancellable
}