gobreaker

A lightweight, thread-safe circuit breaker for Go that wraps any function call to stop cascading failures when a dependency starts failing.

Library
Go
vv1.0.0
3,703 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
41 /100 Fair
Development Activity 0
Maintenance 0
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
73 /100 Good
Architecture 82
Code Quality 85
Innovation 58
Learning Curve 65

gobreaker is a Go implementation of the circuit breaker pattern: a state machine that wraps calls to an unreliable dependency and, once failures cross a configurable threshold, starts failing fast instead of continuing to hammer the dependency. It tracks closed, half-open, and open states behind a single mutex, using a generation counter to keep in-flight requests from corrupting counts across a state transition, and exposes both a simple Execute(func) wrapper and a two-step Allow()/done() variant for call sites that can’t express work as one closure.

The project is maintained by Sony under the MIT license and ships as two Go modules in one repository: the original github.com/sony/gobreaker (pre-generics, interface{}-based) and github.com/sony/gobreaker/v2, which adds Go generics, a bucketed rolling-window counter, an IsExcluded hook for ignoring specific errors, and a DistributedCircuitBreaker that shares breaker state across processes through a pluggable store.

What You Get

  • A CircuitBreaker type with a single Execute(func() (T, error)) entry point that wraps any call
  • A TwoStepCircuitBreaker for call patterns that need to check-then-report manually via Allow()
  • Configurable trip conditions (ReadyToTrip), success classification (IsSuccessful), and state-change hooks (OnStateChange)
  • Sensible defaults out of the box: trips after 5 consecutive failures, 60s open-state timeout, 1 request allowed while half-open
  • In v2: generics, a bucketed rolling-window counter, an IsExcluded hook, and a DistributedCircuitBreaker for sharing state across replicas via a pluggable store

Common Use Cases

  • Wrapping outbound HTTP calls to a flaky third-party API so repeated failures stop hammering it and start failing fast
  • Protecting calls to a struggling database replica or cache node from queuing up timeouts across every request goroutine
  • Isolating the blast radius when one microservice dependency degrades, so it doesn’t cascade into the caller
  • Sharing one circuit-breaker’s open/closed state across multiple service replicas via v2’s DistributedCircuitBreaker

Under The Hood

Architecture gobreaker centers on a single CircuitBreaker struct guarded by one sync.Mutex, transitioning between StateClosed, StateHalfOpen, and StateOpen inside currentState()/setState(). A monotonically increasing generation counter, bumped in toNewGeneration(), is the key correctness mechanism: beforeRequest() captures the generation at call time and afterRequest() discards any result whose generation has since rolled over, so a slow in-flight call from a pre-trip state can never corrupt the freshly reset Counts after a transition. Execute() is a thin functional wrapper around this before/after pair, recovering and re-panicking on caller panics so the breaker still accounts for failures triggered by panics. TwoStepCircuitBreaker reuses the identical core by exposing beforeRequest/afterRequest as a manual Allow()/done() pair. The separate v2 Go module extends this same core with generics (CircuitBreaker[T]), a Counter interface with a bucketed rolling-window implementation for finer-grained trip decisions, and a DistributedCircuitBreaker[T] that persists SharedState through a pluggable SharedDataStore, letting multiple processes share one breaker’s state. Because every dependent — v1 callers, TwoStepCircuitBreaker, and the entire v2 line — sits directly on this same state machine, a change to the core generation/counts logic would ripple through all of them.

Tech Stack The implementation is Go-stdlib-only at runtime — sync, time, errors, fmt — with zero third-party dependencies in either the v1 module (go.mod targets Go 1.12) or the v2 module (go 1.22, built with toolchain go1.22.10 for generics). The only external dependency anywhere in the repo is github.com/stretchr/testify, used exclusively in test files for assertions. There’s no build tooling beyond the Go toolchain, no framework involved — this is a low-level primitive meant to be composed into other code — and the only runnable artifact besides the library is an example (example/http_breaker.go) wrapping http.Get in a breaker.

Code Quality Both modules ship extensive table-driven test suites using testify/assert, covering state transitions, concurrent goroutine access, generation-rollover races, and panic recovery. CI runs a matrix across two Go versions and both working directories (./ and ./v2), running golangci-lint (with gofmt, goimports, gosec, misspell enabled) and go test -v ./... before building and executing the example binary. Error handling is explicit throughout — sentinel errors (ErrOpenState, ErrTooManyRequests, and v2’s ErrNoSharedStore/ErrNoSharedState) rather than swallowed failures — and every exported symbol carries a doc comment explaining its contract.

API Design The public surface is deliberately small: construct a CircuitBreaker from a Settings struct with every field optional and sane defaults, then call Execute() around any function — that’s the entire integration cost for the common case, keeping boilerplate near zero. The closed/open/half-open pattern with a configurable ReadyToTrip predicate is the textbook circuit-breaker design, not a novel one — v1’s contribution is a clean, dependency-free, generation-safe implementation of it. v2 is where the differentiation shows: an IsExcluded hook to keep errors like context cancellation from counting as failures, a bucketed rolling-window counter for smoother trip decisions than v1’s fixed-interval reset, and a DistributedCircuitBreaker for sharing state across replicas via a pluggable store — capabilities most Go circuit-breaker libraries don’t offer out of the box.

Used by 5 apps in this directory

Go
75%
AGPL 3.0

Coder

Code Editors · Developer Tools · Devops

16,920

Self-hosted cloud development environments and AI coding agents — defined in Terraform, connected via WireGuard, automatically shut down when idle.

View details
91
Repo Health
90
Technical
66
Dependency
Built with
Go 75%
TypeScript 23%
Updated today
Ruby
66%
Other

GitLab

Developer Tools · Devops

24,553

The complete DevOps platform that unifies Git hosting, CI/CD, issue tracking, and security scanning into a single self-hostable application.

View details
87
Repo Health
86
Technical
67
Dependency
Built with
Ruby 66%
JavaScript 20%
Updated today
Go
90%
AGPL 3.0

Pyroscope

Developer Tools · Devops · Monitoring

11,697

An open-source, horizontally scalable continuous profiling platform that pinpoints CPU, memory, and I/O bottlenecks down to the exact line of code, built by Grafana Labs alongside Loki, Tempo, and Mimir.

View details
92
Repo Health
89
Technical
65
Dependency
Built with
Go 90%
Updated yesterday
Go
99%
MIT

temporal

Automation · Devops

23,566

Open-source durable execution platform that keeps mission-critical workflows running through any failure, automatically.

View details
92
Repo Health
85
Technical
67
Dependency
Built with
Go 99%
Updated today
Go
75%
AGPL 3.0

ZITADEL

Authentication

15,268

Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.

View details
92
Repo Health
81
Technical
65
Dependency
Built with
Go 75%
TypeScript 12%
Updated yesterday

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers