resilience4j is a free, open source monitoring & observability project written in Java and released under Apache-2.0. It has 10,763 GitHub stars, 1,501 forks and 306 open issues, and was last pushed 18 days ago. On this registry it ranks #43 of 97 tracked projects in Monitoring & Observability, with 5 head-to-head comparisons available. It gained 3 stars over the last 3 tracked days.

What is resilience4j?

What it is

Resilience4j is a lightweight fault tolerance library for Java, designed around functional programming. It lives in the Java ecosystem and is distributed under the Apache-2.0 license. The library provides higher-order functions, called decorators, that enhance any functional interface, lambda expression or method reference with a Circuit Breaker, Rate Limiter, Retry or Bulkhead. Version 3 of the library requires Java 21, while the project originated as a library for Java 8. The repository has been active for roughly eleven years and carries 10,760 stars, 1,499 forks and 306 open issues.

The concrete problem it solves is the fragility of calls to remote or unreliable dependencies. Instead of forcing a developer to adopt one monolithic resilience framework, Resilience4j lets each call be wrapped in exactly the decorators it needs. Decorators can be stacked, so a single supplier can be protected by a Bulkhead, a Circuit Breaker and a Retry at the same time. When a decorated call fails, the library offers recovery paths, for example recovering from any exception through Try.ofSupplier(...).recover(...). Calls can also be executed asynchronously in a ThreadPoolBulkhead, with a ScheduledExecutorService used to schedule a timeout on a non-blocking CompletableFuture.

Key capabilities

  • Circuit Breaker decorator that wraps a functional interface, lambda expression or method reference and can be created with CircuitBreaker.ofDefaults.
  • Rate Limiter decorator listed among the project topics for controlling call frequency.
  • Retry decorator with configurable attempts and a fixed interval between retries, created via Retry.ofDefaults.
  • Bulkhead and ThreadPoolBulkhead decorators for isolating concurrent calls, including asynchronous execution on a thread pool.
  • Decorator stacking through Decorators.ofSupplier(...), allowing a Bulkhead, Circuit Breaker and Retry to be combined on one supplier.
  • Recovery support through Try.ofSupplier(decoratedSupplier).recover(...) for handling thrown exceptions.
  • Metrics as a first-class topic, alongside the resilience decorators themselves.

Who uses it and how

  • Teams protecting calls to a backend service, as shown by the backendService.doSomething(param1, param2) example that is decorated and executed.
  • Applications that need to combine several resilience patterns on one call, using Decorators.ofSupplier to stack a Bulkhead, Circuit Breaker and Retry.
  • Services that execute protected calls asynchronously, using ThreadPoolBulkhead with a ScheduledExecutorService to schedule timeouts on a non-blocking CompletableFuture.
  • Codebases that want to protect an existing lambda expression without decorating it, by calling circuitBreaker.executeSupplier(backendService::doSomething) directly.
  • Systems that need to recover from failures rather than propagate them, using the Try recovery path to return a fallback value.

Getting started

The library is consumed as Java artifacts published under the io.github.resilience4j group, with release and snapshot builds available on the Sonatype OSS repository and referenced through the project's Nexus badges. Stacking multiple decorators on one supplier requires the resilience4j-all dependency.

When to use it — and

project readme (upstream, from github) — read inline

= Fault tolerance library designed for functional programming :author: Robert Winkler and Bohdan Storozhuk :icons: :toc: macro :numbered: 1 ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: :important-caption: :heavy_exclamation_mark: :caution-caption: :fire: :warning-caption: :warning: endif::[]

image:https://github.com/resilience4j/resilience4j/actions/workflows/gradle-build.yml/badge.svg["Build Status"] image:https://img.shields.io/nexus/r/io.github.resilience4j/resilience4j-circuitbreaker?server=https%3A%2F%2Foss.sonatype.org["Release"] image:https://img.shields.io/nexus/s/io.github.resilience4j/resilience4j-circuitbreaker?server=https%3A%2F%2Foss.sonatype.org["Snapshot"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"]

image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=coverage["Coverage", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=sqale_rating["Maintainability", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=reliability_rating["Reliability", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=security_rating["Security", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=vulnerabilities["Vulnerabilities", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=bugs["Bugs", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"]

image:https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg["SWUbanner",link="https://vshymanskyy.github.io/StandWithUkraine"]

toc::[]

== Introduction

Resilience4j is a lightweight fault tolerance library designed for functional programming. Resilience4j provides higher-order functions (decorators) to enhance any functional interface, lambda expression or method reference with a Circuit Breaker, Rate Limiter, Retry or Bulkhead. You can stack more than one decorator on any functional interface, lambda expression or method reference. The advantage is that you have the choice to select the decorators you need and nothing else.

Resilience4j 3 requires Java 21.

[source,java]

// Create a CircuitBreaker with default configuration CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("backendService");

// Create a Retry with default configuration // 3 retry attempts and a fixed time interval between retries of 500ms Retry retry = Retry.ofDefaults("backendService");

// Create a Bulkhead with default configuration Bulkhead bulkhead = Bulkhead.ofDefaults("backendService");

Supplier supplier = () -> backendService .doSomething(param1, param2);

// Decorate your call to backendService.doSomething() // with a Bulkhead, CircuitBreaker and Retry // **note: you will need the resilience4j-all dependency for this Supplier decoratedSupplier = Decorators.ofSupplier(supplier) .withCircuitBreaker(circuitBreaker) .withBulkhead(bulkhead) .withRetry(retry) .decorate();

// Execute the decorated supplier and recover from any exception String result = Try.ofSupplier(decoratedSupplier) .recover(throwable -> "Hello from Recovery").get();

// When you don't want to decorate your lambda expression, // but just execute it and protect the call by a CircuitBreaker. String result = circuitBreaker .executeSupplier(backendService::doSomething);

// You can also run the supplier asynchronously in a ThreadPoolBulkhead ThreadPoolBulkhead threadPoolBulkhead = ThreadPoolBulkhead .ofDefaults("backendService");

// The Scheduler is needed to schedule a timeout on a non-blocking CompletableFuture ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3); TimeLimiter timeLimiter = TimeLimiter.of(Duration.ofSeconds(1));

CompletableFuture future = Decorators.ofSupplier(supplier) .withThreadPoolBulkhead(threadPoolBulkhead) .withTimeLimiter(timeLimiter, scheduler) .withCircuitBreaker(circuitBreaker) .withFallback(asList(TimeoutException.class, CallNotPermittedException.class, BulkheadFullException.class), throwable -> "Hello from Recovery") .get().toCompletableFuture();


NOTE: With Resilience4j you don’t have to go all-in, you can https://mvnrepository.com/artifact/io.github.resilience4j[*pick what you need*].

== Documentation

Setup and usage is described in our https://resilience4j.readme.io/docs[User Guide].

== Overview

Resilience4j provides several core modules:

  • resilience4j-circuitbreaker: Circuit breaking
  • resilience4j-ratelimiter: Rate limiting
  • resilience4j-bulkhead: Bulkheading
  • resilience4j-retry: Automatic retrying (sync and async)
  • resilience4j-timelimiter: Timeout handling
  • resilience4j-cache: Result caching

There are also add-on modules for metrics, Feign, Kotlin, Spring, Ratpack, Vertx, RxJava2 and more.

NOTE: Find out full list of modules in our https://resilience4j.readme.io/docs#section-modularization[User Guide].

TIP: For core modules package or +Decorators+ builder see https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-all[resilience4j-all].

== Best Practices

=== Instance Management: When to Share vs. Not Share Instances

One of the most important concepts for newcomers to understand is when to create separate instances versus when to share instances across different remote services or backends.

[IMPORTANT]

The Golden Rule: Create a unique instance (with a unique ID) for each protected remote service or backend you communicate with.

==== Why Unique Instances Matter

Creating separate instances for each backend service is critical for:

  1. Proper metrics collection - Each instance tracks its own metrics, allowing you to monitor the health of individual services
  2. Isolation of failures - If Service A fails, it won't affect the resilience patterns protecting Service B
  3. Independent configuration - Different backends may require different circuit breaker thresholds, concurrency limits, rate limits, or retry policies

==== Instance-Aware vs. Non-Instance-Aware Patterns

Different resilience patterns have different requirements for instance separation:

===== Instance-Aware Patterns (MUST NOT Share)

These patterns maintain state that is specific to a particular service and MUST have separate instances:

  • CircuitBreaker - Tracks failure rates and state (OPEN/CLOSED/HALF_OPEN) per service

[source,java]

// CORRECT: Separate CircuitBreaker for each service CircuitBreaker paymentServiceCB = CircuitBreaker.ofDefaults("paymentService"); CircuitBreaker inventoryServiceCB = CircuitBreaker.ofDefaults("inventoryService"); CircuitBreaker notificationServiceCB = CircuitBreaker.ofDefaults("notificationService");

// WRONG: Sharing one CircuitBreaker across multiple services CircuitBreaker sharedCB = CircuitBreaker.ofDefaults("shared"); // DON'T DO THIS! // If one service fails, the circuit opens for ALL services!

  • Bulkhead (both SemaphoreBulkhead and ThreadPoolBulkhead) - Manages concurrent call limits per service

[source,java]

// CORRECT: Separate Bulkhead for each service Bulkhead paymentBulkhead = Bulkhead.ofDefaults("paymentService"); Bulkhead inventoryBulkhead = Bulkhead.ofDefaults("inventoryService");

// WRONG: Sharing limits resource isolation benefits Bulkhead sharedBulkhead = Bulkhead.ofDefaults("shared"); // DON'T DO THIS!

  • RateLimiter - Controls request rate per service

[source,java]

// CORRECT: Different rate limits for different services RateLimiter apiRateLimiter = RateLimiter.ofDefaults("externalAPI"); RateLimiter dbRateLimiter = RateLimiter.ofDefaults("database");

===== Non-Instance-Aware Patterns (CAN Share, But Better Not To)

These patterns create fresh context for each execution and don't maintain service-specific state:

  • Retry - Configuration can be shared, but unique instances are still recommended for proper metrics
  • TimeLimiter - Timeout settings can be shared if identical across services

[source,java]

// TECHNICALLY OK: Retry doesn't maintain state between calls Retry sharedRetry = Retry.ofDefaults("shared");

// BETTER: Unique instances provide better metrics and monitoring Retry

readme truncated — read the full docs on github

Frequently asked questions

Is resilience4j free to use?

resilience4j is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does resilience4j do?

Resilience4j is a fault tolerance library designed for Java8 and functional programming

What is resilience4j written in?

resilience4j is primarily written in Java. Its source is publicly available at https://github.com/resilience4j/resilience4j, and it has 10,763 GitHub stars.