npm’s 2019 JavaScript ecosystem survey analysis is now available!Get your copy here »


2.7.1 • Public • Published
hapi-rate-limitor logo

Solid and easy to use rate limiting for hapi.

Installation · Usage · Plugin Options · Route Options · Response Headers

Build Status Known Vulnerabilities Latest Version Total downloads Greenkeeper badge

Follow @marcuspoehls for updates!

The Future Studio University supports development of this hapi plugin 🚀
Join the Future Studio University and Skyrocket in Node.js


A hapi plugin to prevent brute-force attacks in your app. The rate limiter uses Redis to store rate-limit related data.

hapi-rate-limitor is built on top of these solid and awesome projects:

Each package solves its own problem perfectly. hapi-rate-limitor composes the solutions of each problem to a solid rate limit plugin for hapi.


hapi v17 (or later) and Node.js v8 (or newer)

This plugin requires hapi v17 (or later) and uses async/await which requires Node.js v8 or newer.


Add hapi-rate-limitor as a dependency to your project:

npm i hapi-rate-limitor


The most straight forward to use hapi-rate-limitor is to register it to your hapi server.

This will use the default configurations of async-ratelimiter and ioredis.

await server.register({
  plugin: require('hapi-rate-limitor')
// went smooth like chocolate with default settings :)

Plugin Options

Customize the plugin’s default configuration with the following options:

  • redis: Object, default: undefined
    • use the redis configuration to pass through your custom Redis configuration to ioredis
  • extensionPoint: String, default: 'onPostAuth'
  • userAttribute: String, default: 'id'
    • credentials property that identifies a user/request on dynamic rate limits. This option is used to access the value from request.auth.credentials.
  • userLimitAttribute: String, default: 'rateLimit'
    • define the property name that identifies the rate limit value on dynamic rate limit. This option is used to access the value from request.auth.credentials.
  • view: String, default: undefined
    • render the view instead of throwing an error (this uses h.view(yourView, { total, remaining, reset }).code(429))
  • enabled: Boolean, default: true
    • enabled or disable the plugin, e.g. when running tests
  • skip: Function, default: () => false
    • an async function to determine whether to skip rate limiting for a given request. The skip function accepts the incoming request as the only argument

All other options are directly passed through to async-ratelimiter.

await server.register({
  plugin: require('hapi-rate-limitor'),
  options: {
    redis: {
      port: 6379,
      host: ''
    extensionPoint: 'onPreAuth',
    namespace: 'hapi-rate-limitor',
    max: 2,                                     // a maximum of 2 requests
    duration: 1000                              // per second (the value is in milliseconds),
    userAttribute: 'id',
    userLimitAttribute: 'rateLimit',
    view: 'rate-limit-exceeded',                // render this view when the rate limit exceeded
    enabled: true
    skip: async (request) => {
      return request.path.includes('/admin')    // example: disable rate limiting for the admin panel
// went smooth like chocolate :)

Please check the async-ratelimiter API for all options.

Route Options

Customize the plugin’s default configuration on routes. A use case for this is a login route where you want to reduce the request limit even lower than the default limit.

On routes, hapi-rate-limitor respects all options related to rate limiting. Precisely, all options that async-ratelimiter supports. It does not accept Redis connection options or identifiers for dynamic rate limiting.

All other options are directly passed through to async-ratelimiter.

await server.register({
  plugin: require('hapi-rate-limitor'),
  options: {
    redis: {
      port: 6379,
      host: ''
    namespace: 'hapi-rate-limitor',
    max: 60,             // a maximum of 60 requests
    duration: 60 * 1000, // per minute (the value is in milliseconds)
await server.route({
  method: 'POST',
  path: '/login',
  options: {
    handler: () {
      // do the login handling
    plugins: {
      'hapi-rate-limitor': {
        max: 5,              // a maximum of 5 requests
        duration: 60 * 1000, // per minute
        enabled: false       // but it’s actually not enabled ;-)
// went smooth like chocolate :)

Please check the async-ratelimiter API for all options.

Dynamic Rate Limits

To make use of user-specific rate limits, you need to configure the userIdKey and userLimitKey attributes in the hapi-rate-limitor options. These attributes are used to determine the rate limit properties. The userIdKey is the property name that uniquely identifies a user. The userLimitKey is the property name that contains the rate limit value.

await server.register({
  plugin: require('hapi-rate-limitor'),
  options: {
    userLimitId: 'id',
    userLimitKey: 'rateLimit',
    max: 500,                // a maximum of 500 requests (default is 2500)
    duration: 60 * 60 * 1000 // per hour (the value is in milliseconds)
    // other plugin options

This will calculate the maximum requests individually for each authenticated user based on the user’s id and 'rateLimit' attributes. Imagine the following user object as an authenticated user:

 * the authenticated user object may contain
 * a custom rate limit attribute. In this
 * case, it’s called "rateLimit".
request.auth.credentials = {
  id: 'custom-uuid',
  rateLimit: 1750,
  name: 'Marcus'
  // ... further attributes

For this specific user, the maximum amount of requests is 1750 per hour (and not the plugin’s default 500).

hapi-rate-limitor uses the plugin’s limit if the request is unauthenticated or request.auth.credentials doesn’t contain a rate-limit-related attribute.

Response Headers

The plugin sets the following response headers:

  • X-Rate-Limit-Limit: total request limit (max) within duration
  • X-Rate-Limit-Remaining: remaining quota until reset
  • X-Rate-Limit-Reset: time since epoch in seconds that the rate limiting period will end

Feature Requests

Do you miss a feature? Please don’t hesitate to create an issue with a short description of your desired addition to this plugin.

Links & Resources


  1. Create a fork
  2. Create your feature branch: git checkout -b my-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request 🚀


MIT © Future Studio  ·  GitHub @futurestudio  ·  Twitter @futurestud_io


npm i hapi-rate-limitor

Downloadsweekly downloads









last publish


  • avatar
  • avatar
  • avatar
  • avatar
Report a vulnerability