On this page

Tiered Rate Limits

Apply different rate limits based on user tiers such as free, pro, and enterprise plans using the built-in tiers and tier options.

How It Works

Define your tier configurations in tiers, then provide a tier resolver function that returns the tier name for each request. hitlimit picks the correct limit and window automatically.

hitlimit({
  tiers: {
    free:       { limit: 100,   window: '1h'  },
    pro:        { limit: 1000,  window: '1h'  },
    enterprise: { limit: 10000, window: '1h'  }
  },
  tier: (req) => req.user?.tier || 'free'
})

TierConfig

FieldTypeDescription
limitnumberMaximum requests per window for this tier (required)
windowstring | numberTime window override for this tier. Falls back to the top-level window if omitted.

Different Windows per Tier

Each tier can have its own window. Free users get a strict hourly limit; pro users get a more generous per-minute limit:

hitlimit({
  tiers: {
    free: { limit: 60,   window: '1h'  },  // 60/hour
    pro:  { limit: 500,  window: '1m'  },  // 500/minute
  },
  tier: (req) => req.user?.tier || 'free'
})

Async Tier Resolution

The tier function can return a Promise, useful for database lookups:

hitlimit({
  tiers: {
    free:  { limit: 100,  window: '1h' },
    pro:   { limit: 5000, window: '1h' },
  },
  tier: async (req) => {
    const user = await getUserFromToken(req.headers['authorization'])
    return user?.plan || 'free'
  }
})

Tiered Limits + Custom Key

Combine tiers with a custom key to rate limit per user ID within each tier:

hitlimit({
  tiers: {
    free:  { limit: 100,  window: '1h' },
    pro:   { limit: 5000, window: '1h' },
  },
  tier: (req) => req.user?.plan || 'free',
  key:  (req) => req.user?.id   || req.ip
})

Unknown Tier Fallback

If tier returns a name that isn't in tiers, hitlimit falls back to the top-level limit and window. Always define a default tier (e.g. 'free') or set a top-level limit as a safety net:

hitlimit({
  limit: 50,      // fallback if tier not found
  window: '1h',
  tiers: {
    pro: { limit: 5000 }
  },
  tier: (req) => req.user?.plan || 'unknown'
})