When an external API is down, continuing to send requests wastes resources and may get your API key throttled.
When an external API is down, continuing to send requests wastes resources and may get your API key throttled. Implement a circuit breaker: after N consecutive failures, stop calling the API and alert your team. Periodically test if the API has recovered before re-enabling the workflow.
Real-world example: A workflow calls a third-party inventory API every 5 minutes. The API goes down for 2 hours. Without a circuit breaker, you accumulate 24 failed executions and 72 wasted retry attempts. With a circuit breaker, you detect the outage after 3 failures and stop until it recovers.
// Code node: "Circuit Breaker Check"
// Runs at the start of the workflow, before any API calls
// Read circuit breaker state from a persistent store (Google Sheet or DB)
// The previous node should fetch the current state
const state = $input.first().json;
const FAILURE_THRESHOLD = 3; // Open circuit after 3 consecutive failures
const RECOVERY_TIMEOUT_MS = 300000; // Try again after 5 minutes (300,000 ms)
const now = Date.now();
const consecutiveFailures = state.consecutive_failures || 0;
const lastFailureTime = state.last_failure_time
? new Date(state.last_failure_time).getTime()
: 0;
const circuitState = state.circuit_state || 'closed'; // closed | open | half-open
if (circuitState === 'open') {
// Check if enough time has passed to try again
if (now - lastFailureTime > RECOVERY_TIMEOUT_MS) {
return [{
json: {
action: 'proceed',
circuitState: 'half-open',
message: 'Circuit half-open: testing if API has recovered'
}
}];
}
// Circuit is still open -- skip the API call
return [{
json: {
action: 'skip',
circuitState: 'open',
message: `Circuit open: ${consecutiveFailures} consecutive failures. ` +
`Next retry in ${Math.round((RECOVERY_TIMEOUT_MS - (now - lastFailureTime)) / 1000)}s`
}
}];
}
// Circuit is closed or half-open -- proceed with the API call
return [{
json: {
action: 'proceed',
circuitState: circuitState,
consecutiveFailures
}
}];
```text
After the API call, update the circuit breaker state:
```javascript
// Code node: "Update Circuit Breaker State"
// This node has two inputs: success branch and failure branch
const previousState = $('Circuit Breaker Check').first().json;
const apiResult = $input.first().json;
let newState;
if (apiResult.error) {
// Failure -- increment counter
const failures = (previousState.consecutiveFailures || 0) + 1;
const isOpen = failures >= 3; // FAILURE_THRESHOLD
newState = {
consecutive_failures: failures,
last_failure_time: new Date().toISOString(),
circuit_state: isOpen ? 'open' : previousState.circuitState,
last_updated: new Date().toISOString()
};
if (isOpen && previousState.circuitState !== 'open') {
// Circuit just opened -- send alert
newState.alert = `Circuit OPENED for inventory API after ${failures} consecutive failures`;
}
} else {
// Success -- reset counter
newState = {
consecutive_failures: 0,
last_failure_time: null,
circuit_state: 'closed',
last_updated: new Date().toISOString()
};
if (previousState.circuitState === 'half-open') {
newState.alert = 'Circuit CLOSED: inventory API has recovered';
}
}
return [{ json: newState }];
// Next node: Write this state back to the persistent store
```text
```yaml
Circuit breaker state transitions:
CLOSED (normal operation):
API call succeeds --> stay CLOSED, reset failure count
API call fails --> increment failure count
Failure count >= 3 --> transition to OPEN, send alert
OPEN (API assumed down):
Skip all API calls
After 5 minutes --> transition to HALF-OPEN
HALF-OPEN (testing recovery):
API call succeeds --> transition to CLOSED, send recovery alert
API call fails --> transition to OPEN, reset timer
```text
This protects your workflows from wasting resources on a down API and gives you immediate notification when an integration breaks or recovers.
**Related:** [Use "Pin Data" to Freeze Node Output](../testing-and-debugging/01-use-pin-data-to-freeze-node-output.md) | [Break Large Workflows into Sub-Workflows](../workflow-architecture/01-break-large-workflows-into-sub-workflows.md)
I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.