Moleculer Circuit Breaker: Minimal Design for Protecting Service Calls
Learn how to enable Moleculer’s built‑in circuit breaker, where it applies, what events to watch, and when you’d need an external solution.
20 Nov 2025, 12:30 UTC

Requirements
In a Moleculer‑based micro‑service system you want to stop a cascade of failures when a remote action becomes unreliable. The circuit breaker must:
- Monitor error rate or latency of calls to a specific action.
- Open automatically when a configurable threshold is exceeded within a time window.
- Reject further calls with a predictable error while open.
- After a timeout, allow a single trial request (half‑open) to decide whether to close.
- Emit observable events so operators can see state changes.
Smallest Suitable Design
Moleculer ships a built‑in circuit breaker that can be activated per service. Adding the following block to a service schema enables it for every action in that service:
{
name: 'orders',
circuitBreaker: {
enabled: true,
threshold: 0.5, // 50 % failures opens the breaker
windowTime: 10000, // 10 s sliding window
minRequestCount: 20, // need at least 20 requests before evaluating
timeout: 5000 // 5 s before trying a half‑open request
},
actions: {
// …
}
}
Place this file in your service directory and start the Moleculer broker as usual; the broker wraps each action call automatically.
Trust/Data Boundaries
The breaker lives at the broker’s request/response proxy layer. It treats every remote action accessed via broker.call as an untrusted endpoint. Calls that stay inside the same process (e.g., this.actions.otherAction.call(ctx)) bypass the breaker unless you explicitly wrap them with this.Promise.method or a custom middleware.
Operational Checks
To verify the breaker is working:
- Start the broker and subscribe to its lifecycle events:
broker.on('circuitBreaker.open', (payload) => console.log('OPEN', payload));
broker.on('circuitBreaker.halfOpen', (payload) => console.log('HALF‑OPEN', payload));
broker.on('circuitBreaker.close', (payload) => console.log('CLOSE', payload));
- Invoke the protected action repeatedly (e.g., in a test script) and watch for the
CircuitBreakerErrorafter the configured number of failures. - After the
timeout period, confirm a single trial request is allowed; if it succeeds, acircuitBreaker.closeevent follows.
Run the test script with Node.js (≥12) and ensure the process has permission to create the broker (no special rights needed).
Failure Modes
When the failure proportion exceeds threshold within windowTime, the breaker transitions to open. Subsequent calls to the protected action are rejected instantly with:
new MoleculerError('Circuit breaker is open', 500, 'CIRCUIT_BREAKER_OPEN', {})
While open, no network traffic is sent to the remote service, preventing further load. After timeout milliseconds the breaker goes half‑open and permits exactly one call. If that call succeeds, the breaker closes; if it fails, it re‑opens immediately.
Conditions That Would Change the Design
Consider replacing the built‑in breaker with an external library or custom middleware when:
- The transport used does not support request/response semantics (e.g., a pure event‑only bus).
- You need circuit breaking across language boundaries where Moleculer’s broker is not involved.
- Different actions within the same service require distinct thresholds or windows.
- You want to integrate with a centralized monitoring system that expects a standard breaker API (e.g., Hystrix‑style metrics).
In those cases you would remove the circuitBreaker block from the service schema and apply your own middleware that wraps broker.call or the transport layer.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.