resilience4cata 1.0.0-RC2: try it before 1.0
The API of resilience4cata is frozen: 1.0.0-RC2 is on Maven Central, and unless your feedback shows that something has to change, 1.0.0 will ship with the same API.
4 November 2026 · by fabiangftech, author of resilience4cata
What a release candidate means here
Until now, every minor version could change the API, and the changelog listed what broke. From 1.0.0 that stops: minor and patch versions of one major keep working what the compatibility page lists, which is the Java API, code generated by an older processor, configuration keys, metric names, the endpoints' JSON and error codes.
The release candidates are the last chance to change any of that cheaply. The build already treats the API as frozen: every published module is compared with 1.0.0-RC2 on Maven Central, and an incompatible change fails the build. If you try the candidate and something is awkward, a name, a default, an error message or a missing hook, now is when it can still be fixed.
What resilience4cata is
resilience4cata is a resilience library for Java 21+: retry, circuit breaker, rate limiter, timeout, bulkhead, fallback, plus hedging and an adaptive concurrency limit. You put annotations on an interface or a class, and an annotation processor writes a plain Java class next to it at compile time. There is no proxy, aspect or agent. The generated method calls each policy directly, and a successful call allocates nothing.
Measured AWS
c7g.xlarge(Graviton3), one thread, ns per call, on the code of 1.0.0-RC1 (RC2 changes only the framework integrations), against Resilience4j 2.4.0 with the same settings. From the landing page's rows on the release candidate.
| Call | resilience4cata | Resilience4j 2.4.0 |
|---|---|---|
| Retry, first attempt succeeds | 1.4 ns, 0 B | 22.9 ns, 0 B |
| Circuit breaker, every call succeeds | 1.9 ns, 0 B | 89.9 ns, 0 B |
| Sync timeout | 23.6 ns, 0 B | 8907.6 ns, 183 B |
| Bulkhead, slots free | 17.3 ns, 0 B | 20.1 ns, 0 B |
With four threads the circuit breaker stays at 1.9 ns, while Resilience4j's goes to 849.5 ns. The first article explains where the difference comes from.
What changed on the way to 1.0
Before the API froze, four reviewers went through the library: an API designer, a performance reviewer, a newcomer and someone deciding whether to adopt it. Their findings, and what was done with each one, are in the plan to 1.0. In short:
- The last API changes. Two are incompatible and small:
CircuitBreakerEvent.CallNotPermittedis nowRejected, like the other policies' rejection events, and two hedge constants are no longer public. Types that carry a call's result accept nullable types, which helps Kotlin and NullAway users. - Promises written down. The compatibility page says what stays compatible within a major version and what may grow in a minor one, such as new enum constants, new event record components or new policies.
- Four races fixed. They were in the bulkhead with
maxWait, the adaptive limit, the rate limiter and the sync timeout. Three were reproduced first, by a test that replays the interleaving or by jcstress, and those tests were checked by mutation; the rate limiter's could only be confirmed by reading the code. CI runs jcstress only on x86, so it also ran once on Graviton3: all 65 tests passed, in 2598 configurations. - Documentation. There is a recipe for an HTTP call with a retry and a circuit breaker, tested against a real server, and a step in the quickstart that shows the breaker open. The migration guide now maps Resilience4j's metric names to ours.
- RC2: a missing annotation processor is an error. The annotations have
CLASSretention, so if the processor did not run, nothing noticed and the beans ran unprotected. Now Spring Boot fails the startup with R4C-SPR-006, Micronaut fails the bean with R4C-MN-007, and Quarkus fails the build with R4C-QK-008. Each message names the type and the dependency to add.
The changelog has the full list.
Try it
Gradle
dependencies {
implementation 'dev.resilience4cata:resilience4cata-all:1.0.0-RC2'
annotationProcessor 'dev.resilience4cata:resilience4cata-processor:1.0.0-RC2'
}
Gradle (Kotlin)
dependencies {
implementation("dev.resilience4cata:resilience4cata-all:1.0.0-RC2")
annotationProcessor("dev.resilience4cata:resilience4cata-processor:1.0.0-RC2")
}
Maven
<dependency>
<groupId>dev.resilience4cata</groupId>
<artifactId>resilience4cata-all</artifactId>
<version>1.0.0-RC2</version>
</dependency>
<!-- in the maven-compiler-plugin <configuration> -->
<annotationProcessorPaths>
<path>
<groupId>dev.resilience4cata</groupId>
<artifactId>resilience4cata-processor</artifactId>
<version>1.0.0-RC2</version>
</path>
</annotationProcessorPaths>
The pages of this site still show 0.13.0 in their build snippets; write 1.0.0-RC2 instead. Then the quickstart protects a flaky call in about five minutes. For an application, start from the guide for Spring Boot, Micronaut or Quarkus. If you use Resilience4j today, the migration guide maps its registries, configs, decorators and Spring annotations to resilience4cata.
What helps most
Anything you would want changed after 1.0 but could not, because it would break compatibility:
- names, defaults or annotation attributes that surprised you;
- an error message that did not tell you what to do;
- a framework setup that did not work as the guide says;
- something you needed and had to work around.
Open an issue or start a discussion on GitHub. "I tried it and it just worked" is useful too. Security problems go through private reporting, as SECURITY.md explains.
What comes next
If nothing needs to change, 1.0.0 follows with the same API, and the compatibility promise starts. If something does need to change, there will be another candidate first.