Introduction
fluxgo is an adaptive circuit breaker for Go services, API-compatible with sony/gobreaker.
A classic circuit breaker trips when the failure rate crosses a fixed threshold. That threshold is a compromise: low enough to catch an outage, high enough not to trip on noise. When a dependency slows down without failing outright, a static breaker keeps sending traffic until requests finally start timing out.
fluxgo computes its failure-rate threshold θₜ from live latency signals instead:
- EWMA latency (Sₜ): a smoothed mean, compared with a healthy baseline captured during warmup.
- Rolling P95 or P99 (Pₜ): tail latency over a fixed window, updated with zero allocations.
The two are combined into a degradation ratio Dₜ, which scales the threshold:
Dt = W1 · (St / Sbase) + W2 · (Pt / Pbase)theta_t = clamp(ThetaBase / Dt, ThetaMin, ThetaMax)When latency doubles (Dt = 2), θₜ halves, so the circuit opens at half the
failure rate a static breaker would need. When latency improves (Dt < 1), θₜ
rises and the circuit becomes more tolerant.
Built-in safeguards
Section titled “Built-in safeguards”- Warmup: for the first
WarmupDuration(30 s by default) fluxgo learns the baseline and behaves like a static breaker. - Anti-flapping: after any transition, the circuit cannot trip again until
MinDwellTimehas passed. - Slow requests: a call slower than
Pₜ × SlowRequestMargincounts as a failure internally. The result returned to your code is unchanged.
Performance
Section titled “Performance”| Benchmark | Latency per call | Allocations |
|---|---|---|
Execute(), closed (full pipeline) | ~656 ns | 0 |
Execute(), open (fast reject) | ~57 ns | 0 |
Measured on an Intel Core i5-11300H @ 3.10 GHz.
Next: Quick start, or read how the adaptive threshold works.