Circuit Breaker Thresholds — Complete Configuration Guide
In this tutorial, you will learn about Circuit Breaker Thresholds. We cover key concepts, practical examples, and best practices to help you master this topic.
Circuit breaker thresholds determine when the circuit opens, how long it stays open, and when it closes again, directly impacting system resilience and availability.
What You'll Learn
By the end of this tutorial, you will configure failure thresholds, choose appropriate reset timeouts, set success thresholds for half-open recovery, and tune thresholds adaptively.
Why It Matters
Wrong thresholds cause either unnecessary circuit openings (false positives) or delayed failure detection (false negatives). DodaTech tunes thresholds per service based on reliability characteristics.
Real-World Use
DodaTech uses different thresholds for different services: 3 failures for payment processing, 10 for analytics, and 5 for general APIs.
Thresholds Learning Path
flowchart LR
A[Implementation] --> B[Thresholds]
B --> C[Failure Threshold]
B --> D[Reset Timeout]
B --> E[Success Threshold]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Failure Threshold
The failure threshold determines how many consecutive failures trigger the circuit to open. Lower values detect issues faster but may cause false positives.
const thresholds = {
critical: new CircuitBreaker({ threshold: 3, resetTimeout: 10000 }),
standard: new CircuitBreaker({ threshold: 5, resetTimeout: 30000 }),
tolerant: new CircuitBreaker({ threshold: 10, resetTimeout: 60000 })
};
Choosing failure threshold:
- 2-3: Mission-critical services (payment, auth)
- 5: General services (APIs, databases)
- 10+: Non-critical services (analytics, logging)
Time-Based Threshold
Instead of consecutive failures, track failure rate over a time window. This prevents a brief spike from opening the circuit.
class TimeWindowThreshold {
constructor(failureRate, windowMs) {
this.failureRateThreshold = failureRate || 0.5;
this.windowMs = windowMs || 60000;
this.results = [];
}
record(success) {
this.results.push({ success, time: Date.now() });
this.cleanup();
}
shouldOpen() {
if (this.results.length < 10) return false;
const failures = this.results.filter(r => !r.success).length;
return failures / this.results.length >= this.failureRateThreshold;
}
cleanup() {
const cutoff = Date.now() - this.windowMs;
this.results = this.results.filter(r => r.time > cutoff);
}
}
const timeWindowBreaker = new CircuitBreaker({
thresholdStrategy: (failureCount, state) => {
return state.failureRate >= 0.5 && state.totalRequests >= 10;
}
});
Reset Timeout
The reset timeout determines how long the circuit stays open before transitioning to half-open.
class AdaptiveResetTimeout {
constructor(baseTimeout = 30000) {
this.baseTimeout = baseTimeout;
this.multiplier = 1;
this.consecutiveOpenings = 0;
}
getTimeout() {
const timeout = this.baseTimeout * this.multiplier;
this.consecutiveOpenings++;
this.multiplier = Math.min(32, this.multiplier * 2);
return Math.min(timeout, 300000);
}
onClose() {
this.consecutiveOpenings = 0;
this.multiplier = 1;
}
}
// Usage in circuit breaker
class SmartCircuitBreaker extends CircuitBreaker {
constructor(options) {
super(options);
this.timeoutCalculator = new AdaptiveResetTimeout();
}
open() {
this.resetTimeout = this.timeoutCalculator.getTimeout();
this.nextAttempt = Date.now() + this.resetTimeout;
super.open();
}
close() {
this.timeoutCalculator.onClose();
super.close();
}
}
Success Threshold for Half-Open
The success threshold determines how many consecutive successful probes are needed to close the circuit.
// Single success: fast recovery, higher risk of flip-flopping
const fastRecovery = { successThreshold: 1, resetTimeout: 30000 };
// Multiple successes: slower recovery, more stable
const stableRecovery = { successThreshold: 3, resetTimeout: 60000 };
// Progressive success threshold
class ProgressiveSuccessThreshold {
constructor() {
this.attempts = 0;
}
needsMoreSuccesses() {
this.attempts++;
// Need more successes the longer the circuit was open
return this.attempts < Math.ceil(Math.log2(this.attempts + 1));
}
reset() {
this.attempts = 0;
}
}
Common Mistakes
Setting threshold too low -- A threshold of 2 opens the circuit on minor blips. Use at least 3-5 for general services.
Setting threshold too high -- A threshold of 100 means 99 failures happen before protection. Monitor failure rates.
Using the same threshold for all services -- Payment processing needs aggressive thresholds. Analytics can tolerate more failures.
Not considering traffic volume -- Low-traffic services need lower absolute thresholds. High-traffic services can use rate-based thresholds.
Static reset timeout without backoff -- If a service is down for 5 minutes, a 30-second reset timeout causes rapid open/close cycling.
Practice Questions
How does the failure threshold affect system behavior? Lower thresholds detect failures faster but risk false positives. Higher thresholds are more tolerant but delay protection.
What is the advantage of time-based thresholds over consecutive count? Time-based thresholds ignore traffic volume. A brief spike of 5 failures in 1 second should not open the circuit in high-traffic systems.
Why use adaptive reset timeout? If a service keeps failing, increase the timeout to reduce probe frequency and allow more recovery time.
Challenge: Implement a threshold that considers both failure count and failure rate.
function shouldOpen(failureCount, totalRequests, windowMs) {
if (failureCount < 5) return false;
const rate = failureCount / Math.max(1, totalRequests);
return rate > 0.3;
}
FAQ
Mini Project
Build a circuit breaker with configurable threshold strategies, adaptive reset timeout, and time-window failure tracking.
class ConfigurableCircuitBreaker {
constructor(config = {}) {
this.strategy = config.strategy || "consecutive";
this.consecutiveThreshold = config.consecutiveThreshold || 5;
this.rateThreshold = config.rateThreshold || 0.5;
this.windowMs = config.windowMs || 60000;
this.baseResetTimeout = config.resetTimeout || 30000;
this.maxResetTimeout = config.maxResetTimeout || 300000;
this.successThreshold = config.successThreshold || 1;
this.state = "closed";
this.failureCount = 0;
this.successCount = 0;
this.totalRequests = 0;
this.timeline = [];
this.resetTimeout = this.baseResetTimeout;
this.nextAttempt = Date.now();
this.consecutiveOpenings = 0;
}
async call(fn) {
if (this.state === "open") {
if (Date.now() < this.nextAttempt) throw new Error("Open");
this.state = "half-open";
}
this.totalRequests++;
try {
const result = await fn();
this.onSuccess();
return result;
} catch (err) {
this.onFailure();
throw err;
}
}
onSuccess() {
this.timeline.push({ success: true, time: Date.now() });
this.successCount++;
this.failureCount = 0;
if (this.state === "half-open" && this.successCount >= this.successThreshold) {
this.close();
}
}
onFailure() {
this.timeline.push({ success: false, time: Date.now() });
this.failureCount++;
this.successCount = 0;
if (this.shouldOpen()) {
this.open();
}
}
shouldOpen() {
if (this.state === "half-open") return true;
if (this.strategy === "consecutive") {
return this.failureCount >= this.consecutiveThreshold;
}
const recent = this.timeline.filter(t => Date.now() - t.time < this.windowMs);
const failures = recent.filter(t => !t.success).length;
return recent.length >= 10 && failures / recent.length >= this.rateThreshold;
}
open() {
this.state = "open";
this.consecutiveOpenings++;
this.resetTimeout = Math.min(
this.baseResetTimeout * Math.pow(2, this.consecutiveOpenings - 1),
this.maxResetTimeout
);
this.nextAttempt = Date.now() + this.resetTimeout;
this.cleanup();
}
close() {
this.state = "closed";
this.consecutiveOpenings = 0;
this.failureCount = 0;
this.successCount = 0;
}
cleanup() {
const cutoff = Date.now() - this.windowMs * 2;
this.timeline = this.timeline.filter(t => t.time > cutoff);
}
}
What's Next
Now that you understand circuit breaker thresholds, explore configuring half-open probe behavior. Then learn about monitoring circuit breaker health.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro