---
title: "nuxt-backend/rate-limit"
description: "Every export of nuxt-backend/rate-limit, with its signature and where it is defined."
canonical_url: "https://nuxt-backend.dev/docs/reference/api/rate-limit"
---
# nuxt-backend/rate-limit

## Interfaces

### RateLimiterComponents

Defined in: [src/convex/integrations/rate-limit.ts](https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts)

The component handle `setupRateLimiter` reads from your generated
`components` object (the key is picked structurally — pass the whole object).

#### Properties

<table>
<thead>
  <tr>
    <th>
      Property
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Defined in
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a id="ratelimiter">
        
      </a>
      
       <code>
        rateLimiter
      </code>
    </td>
    
    <td>
      <code>
        ComponentApi
      </code>
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
</tbody>
</table>

## Type Aliases

### RateLimitConfig

```ts
type RateLimitConfig = 
  | TokenBucketConfig & ShardedConfig
  | TokenBucketConfig & AsyncConfig
  | FixedWindowConfig & ShardedConfig
  | FixedWindowConfig & AsyncConfig;
```

Defined in: node_modules/@convex-dev/rate-limiter/dist/shared.d.ts:116

One of the supported rate limits.
See [tokenBucketValidator](https://github.com/get-convex/rate-limiter#define-your-rate-limits) and [fixedWindowValidator](https://github.com/get-convex/rate-limiter#define-your-rate-limits) for more
information.

## Variables

### SECOND

```ts
const SECOND: 1000 = 1000;
```

Defined in: node_modules/@convex-dev/rate-limiter/dist/client/index.d.ts:6

---

### MINUTE

```ts
const MINUTE: number;
```

Defined in: node_modules/@convex-dev/rate-limiter/dist/client/index.d.ts:7

---

### HOUR

```ts
const HOUR: number;
```

Defined in: node_modules/@convex-dev/rate-limiter/dist/client/index.d.ts:8

---

### DAY

```ts
const DAY: number;
```

Defined in: node_modules/@convex-dev/rate-limiter/dist/client/index.d.ts:9

---

### DEFAULT_LIMITS

```ts
const DEFAULT_LIMITS: {
  emailOtp: {
     kind: "token bucket";
     rate: 5;
     period: number;
     capacity: 5;
  };
  emailOtpGlobal: {
     kind: "fixed window";
     rate: 300;
     period: number;
  };
  emailOtpAttempt: {
     kind: "token bucket";
     rate: 10;
     period: number;
     capacity: 10;
  };
  emailChange: {
     kind: "token bucket";
     rate: 5;
     period: number;
     capacity: 5;
  };
  billingSync: {
     kind: "token bucket";
     rate: 10;
     period: number;
     capacity: 5;
  };
  ai: {
     kind: "token bucket";
     rate: 30;
     period: number;
     capacity: 10;
  };
  aiBudget: {
     kind: "fixed window";
     rate: 10000;
     period: number;
  };
  mcp: {
     kind: "token bucket";
     rate: 60;
     period: number;
     capacity: 20;
  };
  admin: {
     kind: "token bucket";
     rate: 30;
     period: number;
     capacity: 10;
  };
  invitation: {
     kind: "token bucket";
     rate: 30;
     period: number;
     capacity: 10;
  };
  invitationGlobal: {
     kind: "fixed window";
     rate: 200;
     period: number;
  };
  agentRegistrationGlobal: {
     kind: "fixed window";
     rate: 100;
     period: number;
  };
};
```

Defined in: [src/convex/integrations/rate-limit.ts](https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts)

The package's default rate limits — `emailOtp`, `emailOtpGlobal`,
`emailOtpAttempt`, `emailChange`, `billingSync`, `ai`, `aiBudget`,
`mcp`, `admin`, `invitation`, `invitationGlobal` and
`agentRegistrationGlobal` — guarding the flows the package itself drives.
Keyed per email/entity/caller at the call site (e.g. `limit(ctx, 'emailOtp', { key: hash })`); the `*Global` ones are unkeyed. Extend or
override any of them by passing your own limits to [setupRateLimiter](#setupratelimiter).

Deliberately small: `emailOtp` throttles code *sends* and
`emailOtpAttempt` code *checks*, per address (Better Auth's own
`allowedAttempts` bounds the guesses at one code, but a new code is one
request away), `emailOtpGlobal` caps sends deployment-wide,
`billingSync` guards the live provider fan-out, `ai`/`aiBudget`/`mcp`
back the metered-action, credit-budget and agent surfaces, and
`admin`/`invitation`/`emailChange` cover the signed-in routes where one
caller acts on *other* people or addresses — see `setupAuth`'s route
limits. The package is passwordless: there are no password limits, and an
app that turns passwords on brings its own.

## Covering other auth routes

These names throttle the routes the package wires itself. Better Auth's own
per-path limiter is off by default: it counts in memory, which on Convex
lasts one function call. To throttle another route through it, turn it on
with a durable storage, straight from your auth options:

```ts
setupAuth(components, query, {
  authOptions: {
    rateLimit: {
      enabled: true,
      storage: 'database',
      customRules: { '/organization/create': { window: 60, max: 5 } },
    },
  },
})
```

That limiter counts per IP inside the auth request; the named limits here
count per identity and are enforced before the route runs.

#### Type Declaration

<table>
<thead>
  <tr>
    <th>
      Name
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default value
    </th>
    
    <th>
      Description
    </th>
    
    <th>
      Defined in
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a id="property-emailotp">
        
      </a>
      
       <code>
        emailOtp
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        5
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        5
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Email OTP / verification sends — 5 per minute per address, small burst allowance.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtp.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtp.rate
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtp.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        MINUTE
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtp.capacity
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-emailotpglobal">
        
      </a>
      
       <code>
        emailOtpGlobal
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "fixed window"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        300
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Email OTP sends across the whole deployment — 300 per hour, a fixed window. The backstop the per-address limit cannot be: an attacker rotating addresses to probe an invite gate or run up the email bill hits this ceiling. Raise it when a launch legitimately signs in more than that.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpGlobal.kind
      </code>
    </td>
    
    <td>
      <code>
        "fixed window"
      </code>
    </td>
    
    <td>
      <code>
        'fixed window'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpGlobal.rate
      </code>
    </td>
    
    <td>
      <code>
        300
      </code>
    </td>
    
    <td>
      <code>
        300
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpGlobal.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        HOUR
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-emailotpattempt">
        
      </a>
      
       <code>
        emailOtpAttempt
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        10
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        10
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Code checks — 10 per hour per address, burst 10. Every route that checks a code (sign-in, verification, both steps of an email change, a password reset when the app has passwords) spends one while a code is waiting, right or wrong, keyed by a SHA-256 of the address the code went to. Better Auth refuses a code after three wrong guesses, but <code>
        emailOtp
      </code>
      
       lets five new codes out a minute: without this limit, a guess loop that keeps requesting codes would get fifteen guesses a minute at one address, for as long as it ran. Here it gets ten an hour. Like every limit keyed by an address, someone who spends it can keep that address from signing in with a code for the hour — never without codes going to it, since a check with no code waiting spends nothing — and a passkey still signs it in.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpAttempt.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpAttempt.rate
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpAttempt.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        HOUR
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailOtpAttempt.capacity
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-emailchange">
        
      </a>
      
       <code>
        emailChange
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        5
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        5
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Email changes — 5 per hour per account. The code an email change sends to the new address goes where the caller chose, so it is bounded per account and then by <code>
        emailOtpGlobal
      </code>
      
      , like every other code.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailChange.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailChange.rate
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailChange.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        HOUR
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emailChange.capacity
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-billingsync">
        
      </a>
      
       <code>
        billingSync
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        10
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        5
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Entitlement syncs — 10 per minute per billing entity, small burst for the back-to-back syncs after checkout / top-up. Guards the live provider fan-out <code>
        syncEntitlements
      </code>
      
       performs (see <code>
        setupBilling
      </code>
      
      's <code>
        rateLimiter
      </code>
      
      ).
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        billingSync.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        billingSync.rate
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        billingSync.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        MINUTE
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        billingSync.capacity
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-ai">
        
      </a>
      
       <code>
        ai
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        30
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        10
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Metered AI calls (<code>
        setupAi
      </code>
      
      's default limit) — 30 per minute per billing entity with a burst of 10. Reference by name (<code>
        limit: 'ai'
      </code>
      
      ) or declare your own per-feature limits and name them in <code>
        meteredAction
      </code>
      
      .
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ai.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ai.rate
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ai.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        MINUTE
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ai.capacity
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-aibudget">
        
      </a>
      
       <code>
        aiBudget
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "fixed window"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        10000
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Per-entity credit budget for metered AI (<code>
        setupAi({ budget })
      </code>
      
      ) — a fixed window counting <strong>
        credits
      </strong>
      
      , not calls: each spend consumes its cost in tokens, so the window is "credits per period per billing entity". A fixed window (not a bucket) because a budget is a period allowance that resets, not a smoothed rate. The default is a generous ceiling — <code>
        setupAi({ budget: { units, period } })
      </code>
      
       passes the app's own numbers inline and overrides it. It exists so the name resolves even when a caller names the limit without configuring one.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        aiBudget.kind
      </code>
    </td>
    
    <td>
      <code>
        "fixed window"
      </code>
    </td>
    
    <td>
      <code>
        'fixed window'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        aiBudget.rate
      </code>
    </td>
    
    <td>
      <code>
        10000
      </code>
    </td>
    
    <td>
      <code>
        10_000
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        aiBudget.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        DAY
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-mcp">
        
      </a>
      
       <code>
        mcp
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        60
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        20
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Agent (MCP) session exchanges — 60 per minute per client+user. Guards the token-exchange endpoint agents call on the app's behalf.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mcp.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mcp.rate
      </code>
    </td>
    
    <td>
      <code>
        60
      </code>
    </td>
    
    <td>
      <code>
        60
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mcp.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        MINUTE
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mcp.capacity
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-admin">
        
      </a>
      
       <code>
        admin
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        30
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        10
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Administrator actions — 30 per minute per administrator, burst 10. Covers every <code>
        /admin/*
      </code>
      
       route that acts on somebody else (list, create, update, ban/unban, set role, impersonate, revoke sessions, remove user): each is one privileged call against another person's account, so the ceiling is "a human working fast", not a script. <code>
        /admin/stop-impersonating
      </code>
      
       and <code>
        /admin/has-permission
      </code>
      
       are deliberately exempt — the first is how an administrator leaves an impersonated session and must never be throttled, the second is a read-only check the console calls on render.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        admin.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        admin.rate
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        admin.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        MINUTE
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        admin.capacity
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-invitation">
        
      </a>
      
       <code>
        invitation
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "token bucket"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        30
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; <code>
        capacity
      </code>
      
      : <code>
        10
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Workspace invitations — 30 per hour per inviter, burst 10. An hour window (not a minute) because what matters is the volume one account can send, not its per-second rate. Per <strong>
        inviter
      </strong>
      
      : it bounds one account, not a workspace and not the deployment — <a href="#property-invitationglobal">
        DEFAULT_LIMITS.invitationGlobal
      </a>
      
       is the ceiling that does.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitation.kind
      </code>
    </td>
    
    <td>
      <code>
        "token bucket"
      </code>
    </td>
    
    <td>
      <code>
        'token bucket'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitation.rate
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      <code>
        30
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitation.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        HOUR
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitation.capacity
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-invitationglobal">
        
      </a>
      
       <code>
        invitationGlobal
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "fixed window"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        200
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Invitations across the whole deployment — 200 per hour, a fixed window. The backstop the per-inviter limit cannot be, and the counterpart of <code>
        emailOtpGlobal
      </code>
      
       on the package's other outbound-email path: a workspace with many members, or many accounts acting together, would otherwise put 30 invitation emails per member per hour on your sending domain. Only requests that already cleared <code>
        invitation
      </code>
      
       consume this, so one account's refused excess never eats the shared ceiling. Raise it when a launch legitimately invites more than that.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitationGlobal.kind
      </code>
    </td>
    
    <td>
      <code>
        "fixed window"
      </code>
    </td>
    
    <td>
      <code>
        'fixed window'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitationGlobal.rate
      </code>
    </td>
    
    <td>
      <code>
        200
      </code>
    </td>
    
    <td>
      <code>
        200
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invitationGlobal.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        HOUR
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <a id="property-agentregistrationglobal">
        
      </a>
      
       <code>
        agentRegistrationGlobal
      </code>
    </td>
    
    <td>
      { <code>
        kind
      </code>
      
      : <code>
        "fixed window"
      </code>
      
      ; <code>
        rate
      </code>
      
      : <code>
        100
      </code>
      
      ; <code>
        period
      </code>
      
      : <code>
        number
      </code>
      
      ; }
    </td>
    
    <td>
      -
    </td>
    
    <td>
      Agent client registrations across the whole deployment — 100 per hour, a fixed window. Registration is anonymous by design (OAuth dynamic client registration), so there is no caller to key on: this ceiling bounds how fast anyone can fill the client table. An agent registers once per install, so a real launch stays far below it.
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        agentRegistrationGlobal.kind
      </code>
    </td>
    
    <td>
      <code>
        "fixed window"
      </code>
    </td>
    
    <td>
      <code>
        'fixed window'
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        agentRegistrationGlobal.rate
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        agentRegistrationGlobal.period
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        HOUR
      </code>
    </td>
    
    <td>
      -
    </td>
    
    <td>
      <a href="https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts" rel="nofollow">
        src/convex/integrations/rate-limit.ts
      </a>
    </td>
  </tr>
</tbody>
</table>

## Functions

### setupRateLimiter()

```ts
function setupRateLimiter<Limits>(components, limits?): RateLimiter<{
  emailOtp: {
     kind: "token bucket";
     rate: 5;
     period: number;
     capacity: 5;
  };
  emailOtpGlobal: {
     kind: "fixed window";
     rate: 300;
     period: number;
  };
  emailOtpAttempt: {
     kind: "token bucket";
     rate: 10;
     period: number;
     capacity: 10;
  };
  emailChange: {
     kind: "token bucket";
     rate: 5;
     period: number;
     capacity: 5;
  };
  billingSync: {
     kind: "token bucket";
     rate: 10;
     period: number;
     capacity: 5;
  };
  ai: {
     kind: "token bucket";
     rate: 30;
     period: number;
     capacity: 10;
  };
  aiBudget: {
     kind: "fixed window";
     rate: 10000;
     period: number;
  };
  mcp: {
     kind: "token bucket";
     rate: 60;
     period: number;
     capacity: 20;
  };
  admin: {
     kind: "token bucket";
     rate: 30;
     period: number;
     capacity: 10;
  };
  invitation: {
     kind: "token bucket";
     rate: 30;
     period: number;
     capacity: 10;
  };
  invitationGlobal: {
     kind: "fixed window";
     rate: 200;
     period: number;
  };
  agentRegistrationGlobal: {
     kind: "fixed window";
     rate: 100;
     period: number;
  };
} & Limits>;
```

Defined in: [src/convex/integrations/rate-limit.ts](https://github.com/qruto/nuxt-backend/blob/main/src/convex/integrations/rate-limit.ts)

Configure the [Rate Limiter](https://www.convex.dev/components/rate-limiter) component, pre-seeded with [DEFAULT_LIMITS](#default_limits). Pass extra
named limits to cover your own application functions; they are merged with
(and can override) the package defaults.

#### Type Parameters

<table>
<thead>
  <tr>
    <th>
      Type Parameter
    </th>
    
    <th>
      Default type
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a id="type-parameter-limits">
        
      </a>
      
       <code>
        Limits
      </code>
      
       <em>
        extends
      </em>
      
       <code>
        Record
      </code>
      
      <<code>
        string
      </code>
      
      , <a href="#ratelimitconfig">
        <code>
          RateLimitConfig
        </code>
      </a>
      
      >
    </td>
    
    <td>
      <code>
        Record
      </code>
      
      <<code>
        never
      </code>
      
      , <code>
        never
      </code>
      
      >
    </td>
  </tr>
</tbody>
</table>

#### Parameters

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        components
      </code>
    </td>
    
    <td>
      <a href="#ratelimitercomponents">
        <code>
          RateLimiterComponents
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        limits?
      </code>
    </td>
    
    <td>
      <code>
        Limits
      </code>
    </td>
  </tr>
</tbody>
</table>

#### Returns

`RateLimiter`<{
`emailOtp`: {
`kind`: `"token bucket"`;
`rate`: `5`;
`period`: `number`;
`capacity`: `5`;
};
`emailOtpGlobal`: {
`kind`: `"fixed window"`;
`rate`: `300`;
`period`: `number`;
};
`emailOtpAttempt`: {
`kind`: `"token bucket"`;
`rate`: `10`;
`period`: `number`;
`capacity`: `10`;
};
`emailChange`: {
`kind`: `"token bucket"`;
`rate`: `5`;
`period`: `number`;
`capacity`: `5`;
};
`billingSync`: {
`kind`: `"token bucket"`;
`rate`: `10`;
`period`: `number`;
`capacity`: `5`;
};
`ai`: {
`kind`: `"token bucket"`;
`rate`: `30`;
`period`: `number`;
`capacity`: `10`;
};
`aiBudget`: {
`kind`: `"fixed window"`;
`rate`: `10000`;
`period`: `number`;
};
`mcp`: {
`kind`: `"token bucket"`;
`rate`: `60`;
`period`: `number`;
`capacity`: `20`;
};
`admin`: {
`kind`: `"token bucket"`;
`rate`: `30`;
`period`: `number`;
`capacity`: `10`;
};
`invitation`: {
`kind`: `"token bucket"`;
`rate`: `30`;
`period`: `number`;
`capacity`: `10`;
};
`invitationGlobal`: {
`kind`: `"fixed window"`;
`rate`: `200`;
`period`: `number`;
};
`agentRegistrationGlobal`: {
`kind`: `"fixed window"`;
`rate`: `100`;
`period`: `number`;
};
} & `Limits`>

#### Example

```ts
import { setupRateLimiter } from 'nuxt-backend/rate-limit'
import { components } from './_generated/api'
import { MINUTE } from '@convex-dev/rate-limiter'

export const rateLimiter = setupRateLimiter(components, {
  sendMessage: { kind: 'token bucket', rate: 30, period: MINUTE, capacity: 5 },
})
```


## Sitemap

See the full [sitemap](https://nuxt-backend.dev/sitemap.md) for all pages.
