> ## Documentation Index
> Fetch the complete documentation index at: https://unkey.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Protect any API endpoint from abuse with Unkey's distributed rate limiting. No infrastructure required, just a single API call.

Rate limiting controls how many requests a user, IP, or any identifier can make in a given time window. Unkey provides distributed rate limiting that runs across the Unkey network without infrastructure for you to manage.

## When to use rate limiting

<CardGroup cols={2}>
  <Card title="Prevent abuse" icon="shield">
    Stop bad actors from hammering your endpoints or scraping your data.
  </Card>

  <Card title="Protect costs" icon="piggy-bank">
    Limit expensive operations (AI calls, database queries) before they blow up
    your bill.
  </Card>

  <Card title="Fair usage" icon="scale-balanced">
    Ensure no single user monopolizes shared resources.
  </Card>

  <Card title="Compliance" icon="file-contract">
    Enforce contractual limits (e.g., 10,000 requests/month on a Basic plan).
  </Card>
</CardGroup>

## How it works

<Steps>
  <Step title="Choose an identifier">
    Decide what you're limiting: a user ID, API key, IP address, organization,
    or any string that uniquely identifies the requester.
  </Step>

  <Step title="Set the limit">
    Define how many requests are allowed and over what duration. Example: 100
    requests per minute.
  </Step>

  <Step title="Check on each request">
    Call `limiter.limit(identifier)` and Unkey tells you whether to allow or
    reject the request.
  </Step>
</Steps>

## Quick example

<CodeGroup>
  ```ts TypeScript theme={"theme":"kanagawa-wave"}
  import { Ratelimit } from "@unkey/ratelimit";

  const limiter = new Ratelimit({
    rootKey: process.env.UNKEY_ROOT_KEY,
    namespace: "my-app", // Group related limits together
    limit: 10, // 10 requests...
    duration: "60s", // ...per minute
  });

  export async function handler(req: Request) {
    // Use any identifier: user ID, API key, IP, etc.
    const identifier = req.headers.get("x-user-id") ?? getClientIP(req);

    const { success, remaining, reset } = await limiter.limit(identifier);

    if (!success) {
      return new Response("Too many requests", {
        status: 429,
        headers: {
          "X-RateLimit-Remaining": "0",
          "X-RateLimit-Reset": reset.toString(),
        },
      });
    }

    // Request allowed, continue with your logic
    return new Response(`Hello! ${remaining} requests remaining.`);
  }
  ```

  ```bash cURL theme={"theme":"kanagawa-wave"}
  curl -X POST https://api.unkey.com/v2/ratelimit.limit \
    -H "Authorization: Bearer unkey_..." \
    -H "Content-Type: application/json" \
    -d '{
      "namespace": "my-app",
      "identifier": "user_123",
      "limit": 10,
      "duration": 60000
    }'
  ```
</CodeGroup>

## Standalone vs Key-attached rate limits

Unkey offers two ways to rate limit:

| Approach         | Best for                        | How it works                                                          |
| ---------------- | ------------------------------- | --------------------------------------------------------------------- |
| **Standalone**   | Any endpoint, public or private | You call `limiter.limit()` with any identifier                        |
| **Key-attached** | API key authenticated endpoints | Rate limits are configured per-key and checked during `keys.verify()` |

**Standalone** is what this section covers, it works anywhere, with or without API keys.

**Key-attached** rate limits are configured when you [create API keys](/platform/apis/features/ratelimiting/overview) and are automatically enforced during verification.

<Tip>
  You can use both. Standalone rate limits work well for public endpoints such
  as login and signup. Key-attached rate limits work well for authenticated API
  calls.
</Tip>

## What makes Unkey rate limiting different?

<AccordionGroup>
  <Accordion title="No infrastructure to manage" icon="server">
    No Redis clusters, no Upstash accounts, no connection strings. Install the
    SDK and call the API.
  </Accordion>

  <Accordion title="Globally distributed" icon="globe">
    Requests are processed across Unkey's globally distributed infrastructure.
    Your rate limits are checked close to your users, not in a single region.
    Identifiers approaching their limit converge globally within seconds. See [how rate
    limiting works](/platform/ratelimiting/how-it-works#share-counts-across-regions).
  </Accordion>

  <Accordion title="Performance at scale" icon="gauge-high">
    See real-time performance metrics at
    [ratelimit.unkey.com](https://ratelimit.unkey.com), our global latency and
    throughput benchmarks updated live.
  </Accordion>

  <Accordion title="Timeout and fallback" icon="bolt">
    Configure custom timeout and fallback behavior for resilience when network
    issues occur.
  </Accordion>

  <Accordion title="Per-identifier overrides" icon="user-pen">
    Give specific users higher limits without changing code. "User X gets 1000/min
    instead of 100/min."
  </Accordion>

  <Accordion title="Analytics built in" icon="chart-line">
    See which identifiers are hitting limits, when, and how often, in your
    Unkey dashboard.
  </Accordion>
</AccordionGroup>

## Get started

<Steps>
  <Step title="Create a root key">
    Go to [Settings → Root Keys](https://app.unkey.com/settings/root-keys) and
    create a new key with these permissions: - `ratelimit.*.create_namespace` -
    `ratelimit.*.limit`
  </Step>

  <Step title="Install the SDK">`bash npm install @unkey/ratelimit `</Step>

  <Step title="Add to your code">
    See the [Next.js](/quickstart/ratelimiting/nextjs),
    [Bun](/quickstart/ratelimiting/bun),
    [Express](/quickstart/ratelimiting/express), or
    [Hono](/quickstart/ratelimiting/hono) guides for complete examples.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart/ratelimiting/nextjs">
    Full walkthrough for your framework.
  </Card>

  <Card title="How it works" icon="arrows-split-up-and-left" href="/platform/ratelimiting/how-it-works">
    Understand global consistency and response behavior.
  </Card>

  <Card title="Overrides" icon="sliders" href="/platform/ratelimiting/overrides">
    Give specific users custom limits.
  </Card>

  <Card title="SDK Reference" icon="code" href="/libraries/ts/ratelimit/ratelimit">
    All configuration options and methods.
  </Card>
</CardGroup>
