> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/get-convex/rate-limiter/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get started with Convex Rate Limiter in minutes

This guide walks you through setting up and using the Convex Rate Limiter component with real examples.

<Steps>
  <Step title="Install the Package">
    First, install the rate limiter component:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @convex-dev/rate-limiter
      ```

      ```bash yarn theme={null}
      yarn add @convex-dev/rate-limiter
      ```

      ```bash pnpm theme={null}
      pnpm add @convex-dev/rate-limiter
      ```
    </CodeGroup>
  </Step>

  <Step title="Configure convex.config.ts">
    Create or update `convex/convex.config.ts` to register the component:

    ```typescript convex/convex.config.ts theme={null}
    import { defineApp } from "convex/server";
    import rateLimiter from "@convex-dev/rate-limiter/convex.config.js";

    const app = defineApp();
    app.use(rateLimiter);

    export default app;
    ```
  </Step>

  <Step title="Define Your Rate Limits">
    Create a new file (e.g., `convex/rateLimits.ts`) and define your rate limits:

    ```typescript convex/rateLimits.ts theme={null}
    import { RateLimiter, MINUTE, HOUR } from "@convex-dev/rate-limiter";
    import { components } from "./_generated/api";

    export const rateLimiter = new RateLimiter(components.rateLimiter, {
      // A per-user limit, allowing one every ~6 seconds.
      // Allows up to 3 in quick succession if they haven't sent many recently.
      sendMessage: { kind: "token bucket", rate: 10, period: MINUTE, capacity: 3 },
      
      // One global / singleton rate limit for free trial signups
      freeTrialSignUp: { kind: "fixed window", rate: 100, period: HOUR },
    });
    ```

    <Note>
      **Rate limit strategies:**

      * **Token bucket**: Tokens are added at a steady rate, allowing bursts up to `capacity`
      * **Fixed window**: All tokens granted at once every `period`, with optional rollover
    </Note>
  </Step>

  <Step title="Use in a Mutation - Global Rate Limit">
    Apply a global rate limit that applies to all users:

    ```typescript convex/users.ts theme={null}
    import { mutation } from "./_generated/server";
    import { rateLimiter } from "./rateLimits";

    export const signUpForFreeTrial = mutation({
      args: { /* ... */ },
      handler: async (ctx, args) => {
        // Check global rate limit for free trial signups
        const { ok, retryAfter } = await rateLimiter.limit(ctx, "freeTrialSignUp");
        
        if (!ok) {
          throw new Error(
            `Rate limit exceeded. Please try again in ${Math.ceil(retryAfter! / 1000)} seconds.`
          );
        }
        
        // Proceed with signup logic...
      },
    });
    ```
  </Step>

  <Step title="Use in a Mutation - Per-User Rate Limit">
    Apply a rate limit specific to each user using a `key`:

    ```typescript convex/messages.ts theme={null}
    import { mutation } from "./_generated/server";
    import { v } from "convex/values";
    import { rateLimiter } from "./rateLimits";

    export const sendMessage = mutation({
      args: {
        text: v.string(),
      },
      handler: async (ctx, args) => {
        const user = await ctx.auth.getUserIdentity();
        if (!user) {
          throw new Error("Not authenticated");
        }
        
        // Rate limit per user
        const { ok, retryAfter } = await rateLimiter.limit(ctx, "sendMessage", {
          key: user.subject,
        });
        
        if (!ok) {
          throw new Error(
            `You're sending messages too quickly. Please wait ${Math.ceil(retryAfter! / 1000)} seconds.`
          );
        }
        
        // Save the message
        await ctx.db.insert("messages", {
          text: args.text,
          userId: user.subject,
          timestamp: Date.now(),
        });
      },
    });
    ```
  </Step>

  <Step title="Error Handling with throws Option">
    For cleaner code, use the `throws` option to automatically throw errors when rate limits are exceeded:

    ```typescript convex/auth.ts theme={null}
    import { mutation } from "./_generated/server";
    import { v } from "convex/values";
    import { RateLimiter, HOUR, isRateLimitError } from "@convex-dev/rate-limiter";
    import { components } from "./_generated/api";

    const rateLimiter = new RateLimiter(components.rateLimiter, {
      failedLogins: { kind: "token bucket", rate: 10, period: HOUR },
    });

    export const login = mutation({
      args: {
        email: v.string(),
        password: v.string(),
      },
      handler: async (ctx, args) => {
        try {
          // Automatically throw if rate limit is exceeded
          await rateLimiter.limit(ctx, "failedLogins", {
            key: args.email,
            throws: true,
          });
          
          // Attempt login...
          const success = await attemptLogin(args.email, args.password);
          
          if (success) {
            // Reset rate limit on successful login
            await rateLimiter.reset(ctx, "failedLogins", { key: args.email });
          }
          
          return { success };
        } catch (error) {
          if (isRateLimitError(error)) {
            throw new Error(
              `Too many failed login attempts. Please try again later.`
            );
          }
          throw error;
        }
      },
    });

    function attemptLogin(email: string, password: string) {
      // Your login logic here
      return true;
    }
    ```

    <Warning>
      When using `throws: true`, the rate limiter throws a `ConvexError` with data `{kind: "RateLimited", name, retryAfter}`. Use `isRateLimitError()` to check if an error is a rate limit error.
    </Warning>
  </Step>
</Steps>

## What You've Learned

You now know how to:

* Install and configure the Convex Rate Limiter component
* Define rate limits with different strategies (token bucket and fixed window)
* Apply global rate limits that affect all users
* Apply per-user rate limits using keys
* Handle rate limit errors gracefully
* Reset rate limits when needed

## Next Steps

Explore more advanced features:

* **Custom token counts**: Consume multiple tokens in a single request for LLM token limiting
* **Sharding**: Scale to high throughput with configurable sharding
* **Reservations**: Reserve capacity to avoid starvation on larger requests
* **React hook**: Check rate limits from your frontend with `useRateLimit`

For detailed information, check out the [full Stack post on rate limiting](https://stack.convex.dev/rate-limiting).
