Skip to content

Adapters

Already running rate-limiter-flexible? resilience-pipeline/adapters plugs them in as the backend of a strategy, so you keep your store and get the pipeline’s waiting, telemetry and typed errors on top. The adapters are structurally typed: nothing here imports the library, and any version with the methods below works.

Adapter Turns Into
fromRateLimiterFlexible(limiter, key) any rate-limiter-flexible limiter (Memory, Redis, Postgres, Mongo…) a RateLimiterAlgorithm for RateLimiterStrategy

Using Redis directly? The Redis stores avoid the limitation below, and also cover the cache, lock and circuit state.

import { RateLimiterRedis } from 'rate-limiter-flexible';
import { RateLimiterStrategy, ResiliencePipelineBuilder } from 'resilience-pipeline';
import { fromRateLimiterFlexible } from 'resilience-pipeline/adapters';
const rlf = new RateLimiterRedis({ storeClient: redis, keyPrefix: 'partner', points: 100, duration: 60 });
// One shared limit:
const partner = new ResiliencePipelineBuilder({ name: 'partner-api' })
.addStrategy((s) => new RateLimiterStrategy(fromRateLimiterFlexible(rlf, 'all'), { queueTimeout: '1s' }, s))
.build();
// One limit per user:
const perUser = new ResiliencePipelineBuilder({ name: 'per-user' })
.addPartitionedRateLimiter({
partitionKey: (ctx) => ctx.properties.get('userId') as string,
limiter: (key, s) => new RateLimiterStrategy(fromRateLimiterFlexible(rlf, key), {}, s),
})
.build();
  • permitLimit is the limiter’s points. The window runs on the limiter’s own clock and store.
  • consume(key, permits) admits a call. A rejection becomes { ok: false, retryAfter: msBeforeNext }, which the strategy turns into waiting (with queueTimeout) or a RateLimiterRejectedError with retryAfter.
  • A store failure (an Error, not a rate-limiter-flexible rejection) is rethrown, so the call fails with it, unless you configure insurance.