From a26d72edc5381448ee21e950344fba89f5507460 Mon Sep 17 00:00:00 2001 From: Stefan Heller Date: Thu, 6 Mar 2025 15:19:47 -0500 Subject: [PATCH 1/3] feat: update documentation for exponential backoff --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cc8e47d..47296b6 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ It's a fork from [LimitDB](https://github.com/limitd/limitdb). - [Use of Redis hash tags](#use-of-redis-hash-tags) - [Breaking changes from `Limitdb`](#breaking-changes-from-limitdb) - [TAKE](#take) +- [TAKEEXPONENTIAL](#takeexponential) - [TAKEELEVATED](#takeelevated) - [Use of fixed window on Take and TakeElevated](#use-of-fixed-window-on-take-and-takeelevated) - [PUT](#put) @@ -260,6 +261,48 @@ The result object has: - `limit` (int): the size of the bucket. - `delta_reset_ms` (int): the time remaining until the bucket is full again, expressed in milliseconds from the current time. +## TAKEEXPONENTIAL + + +### Configuration +You can configure exponential backoff inside your bucket definitions as follows: + +```js +buckets = { + ip: { + size: 10, + per_second: 5, + exponential_backoff: { // Optional. ERL configuration if needed for the bucket. If not defined, defaults will be used if called with takeExponential. + backoff_factor: 3, // Optional. The exponential backoff factor used as the base (n) for ni. Default: the value 2 will be used if nothing is specified.. + multiple_unit: 6, // Optional. The factor used for backoff offset. Used as (m) for m*ni. Default: the value 1000 in miliseconds will be used if nothing is specified. + } + } +} +``` + +This take operation allows the use of exponential backoff rate limits. + +```js +limitd.takeExponential(type, key, { count, configOverride }, (err, result) => { + console.log(result); +}); +``` + +`limitd.takeExponential` takes the following arguments: +- `type`: the bucket type. +- `key`: the identifier of the bucket. +- `count`: the amount of tokens you need. This is optional and the default is 1. +- `configOverride`: caller-provided bucket configuration for this operation + +The result options has: +- `conformant` (boolean): true if the requested amount is conformant to the limit. +- `remaining` (int): the amount of remaining tokens in the bucket. +- `reset` (int / unix timestamp): unix timestamp of the date when the bucket will be full again. +- `limit` (int): the size of the bucket. +- `delta_reset_ms` (int): the time remaining until the bucket is full again, expressed in milliseconds from the current time. +- `backoff_factor` (int): the base exponential factor used for exponential backoff +- `delta_backoff_time` (int): the amount of time until next allowed request expressed in milliseconds from the current time. + ## TAKEELEVATED This take operation allows the use of elevated rate limits if it corresponds. @@ -310,12 +353,12 @@ if erl_triggered // quota left in the quotaKey bucket if !erl_triggered // ERL wasn't triggered in this call, so we haven't identified the remaining quota. ``` -### Use of fixed window in Take and TakeElevated +### Use of fixed window in Take, TakeExponential and TakeElevated By default, the bucket uses the sliding window algorithm to refill tokens. For example, if the bucket is set to 100 tokens per second, it refills 1 token every 10 milliseconds (1000ms / 100 tokens per second). With the fixed window algorithm, the bucket refills at the specified interval. For instance, if set to 100 tokens per second, it refills 100 tokens every second. -To use the fixed window algorithm on `Take` or `TakeElevated`, set the `fixed_window` property in the bucket configuration to `true` (default is `false`). This will refill the bucket at the specified interval +To use the fixed window algorithm on `Take` `TakeExponential` or `TakeElevated`, set the `fixed_window` property in the bucket configuration to `true` (default is `false`). This will refill the bucket at the specified interval Additionally, you can use the `fixed_window` flag in the configOverride parameter. This acts as a feature flag for safe deployment, but it cannot activate the fixed window algorithm if the bucket configuration is set to false. From e855a8944028cf7c83c72e0c623e6b5c809136a9 Mon Sep 17 00:00:00 2001 From: Stefan Heller Date: Thu, 6 Mar 2025 15:32:28 -0500 Subject: [PATCH 2/3] =?UTF-8?q?small=20fix=20=E2=9C=8F=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47296b6..451f13c 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ buckets = { ip: { size: 10, per_second: 5, - exponential_backoff: { // Optional. ERL configuration if needed for the bucket. If not defined, defaults will be used if called with takeExponential. + exponential_backoff: { // Optional. Exp Backoff configuration if needed for the bucket. If not defined, defaults will be used if called with takeExponential. backoff_factor: 3, // Optional. The exponential backoff factor used as the base (n) for ni. Default: the value 2 will be used if nothing is specified.. multiple_unit: 6, // Optional. The factor used for backoff offset. Used as (m) for m*ni. Default: the value 1000 in miliseconds will be used if nothing is specified. } From ddda250b712ecb0071d912ff47b879fdcd0702c1 Mon Sep 17 00:00:00 2001 From: Stefan Heller Date: Fri, 7 Mar 2025 11:45:53 -0500 Subject: [PATCH 3/3] include exponential backoff bucket info --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 451f13c..6854347 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ const limitd = new Limitd({ - `unlimited` (boolean = false): unlimited requests (skip take). - `skip_n_calls` (number): take will go to redis every `n` calls instead of going in every take. - `elevated_limits` (object): elevated limits configuration that kicks in when the bucket is empty. Please refer to the [ERL section](#ERL-Elevated-Rate-Limits) for more details. +- `exponential_backoff` (object): exponential backoff configuration for the use of `takeExponential`. Please refer to the [TAKEEXPONENTIAL section](#takeexponential) for more details. - `fixed_window` (boolean = false): refill at specified interval instead of granular. You can also define your rates using `per_second`, `per_minute`, `per_hour`, `per_day`. So `per_second: 1` is equivalent to `per_interval: 1, interval: 1000`.