Resilience4j | Rate Limiter basics & runtime behavior | Simple example for beginners

In this article we will look at very simple basic example of Resilience4j rate limiter feature & look at runtime behavior of rate limiter. Here is the maven dependency for resilience4j-ratelimiter required for this example.

Rate Limiter Concept

Do not burden service with calls more than it can consume in given period of time. If call load is greater than service’s consumption for given period, then keep calls waiting for reasonable time until next window of period to get turn. Otherwise just timeout the calls & go for alternate recovery path. This will avoid overloading service for given period & also give a graceful way to provide alternate path under heavy load.

Example in this article

Rate Limiter Configuration: Allow 5 calls every 5 seconds. Keep other calls waiting until next 5 second window or maximum of 10 seconds overall.

  • Create mock external service which takes 2 seconds to finish its processing.
  • Create a service client which calls external service using rate limiter with above configurations.
  • Mimic 20 parallel users/executions by calling service client in 20 threads.
  • We will observe how rate limiter behaves for all threads.

Mock Service & client

Here is a mock service which takes 2 seconds to finish processing. Also a service client which decorates calls to external service using rate limiter. Rate limiter is configured to allow 5 calls every 5 seconds & keep other calls waiting until maximum of 10 seconds.

Rate Limiter in action

Here we will call service client in 20 parallel threads which might mimic 20 parallel users or 20 parallel executions.


Key behavior to look for in output

  • Service calls start:
    • At first you will see “Starting service call” for all 20 threads.
  • 5 calls in 5 seconds window & other waiting:
    • Then you will see that service-call-1 till service-call-5 processing finished around 11:59:45 while other threads were still waiting.
    •  No other processing happens in that 5 seconds window other than above 5 calls.
  • Next 5 calls in next 5 second window:
    • Then you will see that service-call-6 till service-call-10 processing finished after earlier 5 seconds window is over i.e. around 11:59:50
  • Wait time over for last 5 calls:
    • Then you will see that service-call-16 till service-call-20 ended up with io.github.resilience4j.ratelimiter.RequestNotPermitted because 10 second wait time for them was over & they did not get chance to execute in any 5 seconds window.
  • Processing finished for remaining 5 calls:
    • Then you will see that service-call-11 till service-call-15 processing finished around 11:59:55 i.e. after earlier 5 seconds window was over. These logs show after above exception which means these might be under process while above calls failed.

Further reading

Resilience4j | Bulkhead vs. Rate Limiter

Resilience4j Complete Tutorial | Basics with runtime behavior | Simple examples for beginners

One Reply to “Resilience4j | Rate Limiter basics & runtime behavior | Simple example for beginners”

  1. When using the rateLimiterRegistry, the name of the service should be “ExternalLowRateService” instead of “externalConcurrentService”.

Leave a Reply

Your email address will not be published. Required fields are marked *