Skip to content
🔌 circuit breaker based on netflix/hystrix but in ruby, hopefully commands/semaphores eventually too
Ruby Shell
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.


Type Name Latest commit message Commit time
Failed to load latest commit information.


Some tools to aid in resiliency in Ruby. For now, just a circuit breaker (stolen from based on hystrix). Soon much more...

Nothing asynchronous or thread safe yet either, but open to it and would like to see more around it in the future. See more here: jnunemaker/resilient#18.


Add this line to your application's Gemfile:

gem "resilient"

And then execute:

$ bundle

Or install it yourself as:

$ gem install resilient


require "resilient/circuit_breaker"

# default properties for circuit, CircuitBreaker.get is used instead of
# as `get` keeps a registry of circuits by key to prevent
# creating multiple instances of the same circuit breaker for a key; not using
# `get` means you would have multiple instances of the circuit breaker and thus
# separate state and metrics; you can read more in examples/get_vs_new.rb
circuit_breaker = Resilient::CircuitBreaker.get("example")
if circuit_breaker.allow_request?
    # do something expensive
  rescue => boom
    # do fallback
  # do fallback

customize properties of circuit:

circuit_breaker = Resilient::CircuitBreaker.get("example", {
  # at what percentage of errors should we open the circuit
  error_threshold_percentage: 50,
  # do not try request again for 5 seconds
  sleep_window_seconds: 5,
  # do not open circuit until at least 5 requests have happened
  request_volume_threshold: 5,
# etc etc etc

force the circuit to be always open:

circuit_breaker = Resilient::CircuitBreaker.get("example", force_open: true)
# etc etc etc

force the circuit to be always closed (great way to test in production with no impact, all instrumentation still runs which means you can measure in production with config and gain confidence while never actually opening a circuit incorrectly):

circuit_breaker = Resilient::CircuitBreaker.get("example", force_closed: true)
# etc etc etc

customize rolling window to be 10 buckets of 1 second each (10 seconds in all):

circuit_breaker = Resilient::CircuitBreaker.get("example", {
  window_size_in_seconds: 10,
  bucket_size_in_seconds: 1,
# etc etc etc

Default Properties

Property Default Notes
:force_open false allows forcing the circuit open (stopping all requests)
:force_closed false allows ignoring errors and therefore never trip "open" (e.g. allow all traffic through); normal instrumentation will still happen, thus allowing you to "test" configuration live without impact
:instrumenter Instrumenters::Noop what to use to instrument all events that happen (e.g. ActiveSupport::Notifications)
:sleep_window_seconds 5 seconds after tripping circuit before allowing retry
:request_volume_threshold 20 number of requests that must be made within a statistical window before open/close decisions are made using stats
:error_threshold_percentage 50 % of "marks" that must be failed to trip the circuit
:window_size_in_seconds 60 number of seconds in the statistical window
:bucket_size_in_seconds 10 size of buckets in statistical window
:metrics metrics instance used to keep track of success and failure


To ensure that you have clean circuit breakers for each test case, be sure to run the following in the setup for your tests (which resets the default registry and thus clears all the registered circuits) either before every test case or at a minimum each test case that uses circuit breakers.


Note: If you use a non-default registry, you'll need to reset that on your own. If you don't know what I'm talking about, you are fine.


# install dependencies

# run tests

# ...or to auto run tests with guard

# to get a shell to play in


Bug reports and pull requests are welcome on GitHub at


The gem is available as open source under the terms of the MIT License.

Release (for maintainers)

  • increment version based on semver
  • git commit version change
  • script/release (releases to rubygems and git tags)
You can’t perform that action at this time.