---
title: Rate Limiting
description: Define rate limits and interact with them directly from your Cloudflare Worker
image: https://developers.cloudflare.com/dev-products-preview.png
---

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

[Skip to content](#%5Ftop) 

# Rate Limiting

The Rate Limiting API lets you define rate limits and write code around them in your Worker.

You can use it to enforce:

* Rate limits that are applied after your Worker starts, only once a specific part of your code is reached
* Different rate limits for different types of customers or users (ex: free vs. paid)
* Resource-specific or path-specific limits (ex: limit per API route)
* Any combination of the above

The Rate Limiting API is backed by the same infrastructure that serves [rate limiting rules](https://developers.cloudflare.com/waf/rate-limiting-rules/).

Note

You must use version 4.36.0 or later of the [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler).

## Get started

First, add a [binding](https://developers.cloudflare.com/workers/runtime-apis/bindings) to your Worker that gives it access to the Rate Limiting API:

* [  wrangler.jsonc ](#tab-panel-9551)
* [  wrangler.toml ](#tab-panel-9552)

JSONC

```

{

  "main": "src/index.js",

  "ratelimits": [

    {

      "name": "MY_RATE_LIMITER",

      // An identifier you define, that is unique to your Cloudflare account.

      // Must be an integer.

      "namespace_id": "1001",

      // Limit: the number of tokens allowed within a given period in a single

      // Cloudflare location

      // Period: the duration of the period, in seconds. Must be either 10 or 60

      "simple": {

        "limit": 100,

        "period": 60

      }

    }

  ]

}


```

TOML

```

main = "src/index.js"


[[ratelimits]]

name = "MY_RATE_LIMITER"

namespace_id = "1001"


  [ratelimits.simple]

  limit = 100

  period = 60


```

This binding makes the `MY_RATE_LIMITER` binding available, which provides a `limit()` method:

* [  JavaScript ](#tab-panel-9547)
* [  TypeScript ](#tab-panel-9548)

JavaScript

```

export default {

  async fetch(request, env) {

    const { pathname } = new URL(request.url)


    const { success } = await env.MY_RATE_LIMITER.limit({ key: pathname }) // key can be any string of your choosing

    if (!success) {

      return new Response(`429 Failure – rate limit exceeded for ${pathname}`, { status: 429 })

    }


    return new Response(`Success!`)

  }

}


```

TypeScript

```

interface Env {

  MY_RATE_LIMITER: RateLimit;

}


export default {

  async fetch(request, env): Promise<Response> {

    const { pathname } = new URL(request.url)


    const { success } = await env.MY_RATE_LIMITER.limit({ key: pathname }) // key can be any string of your choosing

    if (!success) {

      return new Response(`429 Failure – rate limit exceeded for ${pathname}`, { status: 429 })

    }


    return new Response(`Success!`)

  }

} satisfies ExportedHandler<Env>;


```

The `limit()` API accepts a single argument — a configuration object with the `key` field.

* The key you provide can be any `string` value.
* A common pattern is to define your key by combining a string that uniquely identifies the actor initiating the request (ex: a user ID or customer ID) and a string that identifies a specific resource (ex: a particular API route).

You can define and configure multiple rate limiting configurations per Worker, which allows you to define different limits against incoming request and/or user parameters as needed to protect your application or upstream APIs.

For example, here is how you can define two rate limiting configurations for free and paid tier users:

* [  wrangler.jsonc ](#tab-panel-9553)
* [  wrangler.toml ](#tab-panel-9554)

JSONC

```

{

  "main": "src/index.js",

  "ratelimits": [

    // Free user rate limiting

    {

      "name": "FREE_USER_RATE_LIMITER",

      "namespace_id": "1001",

      "simple": {

        "limit": 100,

        "period": 60

      }

    },

    // Paid user rate limiting

    {

      "name": "PAID_USER_RATE_LIMITER",

      "namespace_id": "1002",

      "simple": {

        "limit": 1000,

        "period": 60

      }

    }

  ]

}


```

TOML

```

main = "src/index.js"


[[ratelimits]]

name = "FREE_USER_RATE_LIMITER"

namespace_id = "1001"


  [ratelimits.simple]

  limit = 100

  period = 60


[[ratelimits]]

name = "PAID_USER_RATE_LIMITER"

namespace_id = "1002"


  [ratelimits.simple]

  limit = 1_000

  period = 60


```

## Configuration

A rate limiting binding has the following settings:

| Setting       | Type   | Description                                                                                                                                                                                                                                   |
| ------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| namespace\_id | string | A string containing a positive integer that uniquely defines this rate limiting namespace within your Cloudflare account (for example, "1001"). Although the value must be a valid integer, it is specified as a string. This is intentional. |
| simple        | object | The rate limit configuration. simple is the only supported type.                                                                                                                                                                              |
| simple.limit  | number | The number of allowed requests (or calls to limit()) within the given period.                                                                                                                                                                 |
| simple.period | number | The duration of the rate limit window, in seconds. Must be either 10 or 60.                                                                                                                                                                   |

Note

Two rate limiting bindings that share the same `namespace_id` — even across different Workers on the same account — share the same rate limit counters for a given key. This is intentional and allows you to enforce a single rate limit across multiple Workers.

If you do not want to share rate limit state between bindings, use a unique `namespace_id` for each binding.

For example, to apply a rate limit of 1500 requests per minute, you would define a rate limiting configuration as follows:

* [  wrangler.jsonc ](#tab-panel-9549)
* [  wrangler.toml ](#tab-panel-9550)

JSONC

```

{

  "ratelimits": [

    {

      "name": "MY_RATE_LIMITER",

      "namespace_id": "1001",

      // 1500 requests - calls to limit() increment this

      "simple": {

        "limit": 1500,

        "period": 60

      }

    }

  ]

}


```

TOML

```

[[ratelimits]]

name = "MY_RATE_LIMITER"

namespace_id = "1001"


  [ratelimits.simple]

  limit = 1_500

  period = 60


```

## Best practices

The `key` passed to the `limit` function, that determines what to rate limit on, should represent a unique characteristic of a user or class of user that you wish to rate limit.

* Good choices include API keys in `Authorization` HTTP headers, URL paths or routes, specific query parameters used by your application, and/or user IDs and tenant IDs. These are all stable identifiers and are unlikely to change from request-to-request.
* It is not recommended to use IP addresses or locations (regions or countries), since these can be shared by many users in many valid cases. You may find yourself unintentionally rate limiting a wider group of users than you intended by rate limiting on these keys.

TypeScript

```

// Recommended: use a key that represents a specific user or class of user

const url = new URL(req.url)

const userId = url.searchParams.get("userId") || ""

const { success } = await env.MY_RATE_LIMITER.limit({ key: userId })


// Not recommended:  many users may share a single IP, especially on mobile networks

// or when using privacy-enabling proxies

const ipAddress = req.headers.get("cf-connecting-ip") || ""

const { success } = await env.MY_RATE_LIMITER.limit({ key: ipAddress })


```

## Locality

Rate limits that you define and enforce in your Worker are local to the [Cloudflare location ↗](https://www.cloudflare.com/network/) that your Worker runs in.

For example, if a request comes in from Sydney, Australia, to the Worker shown above, after 100 requests in a 60 second window, any further requests for a particular path would be rejected, and a 429 HTTP status code returned. But this would only apply to requests served in Sydney. For each unique key you pass to your rate limiting binding, there is a unique limit per Cloudflare location.

## Performance

The Rate Limiting API in Workers is designed to be fast.

The underlying counters are cached on the same machine that your Worker runs in, and updated asynchronously in the background by communicating with a backing store that is within the same Cloudflare location.

This means that while in your code you `await` a call to the `limit()` method:

JavaScript

```

const { success } = await env.MY_RATE_LIMITER.limit({ key: customerId })


```

You are not waiting on a network request. You can use the Rate Limiting API without introducing any meaningful latency to your Worker.

## Accuracy

The above also means that the Rate Limiting API is permissive, eventually consistent, and intentionally designed to not be used as an accurate accounting system.

For example, if many requests come in to your Worker in a single Cloudflare location, all rate limited on the same key, the [isolate](https://developers.cloudflare.com/workers/reference/how-workers-works) that serves each request will check against its locally cached value of the rate limit. Very quickly, but not immediately, these requests will count towards the rate limit within that Cloudflare location.

## Monitoring

Rate limiting bindings are not currently visible in the Cloudflare dashboard. To monitor rate-limited requests from your Worker:

* **[Workers Observability](https://developers.cloudflare.com/workers/observability/)** — Use [Workers Logs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/) and [Traces](https://developers.cloudflare.com/workers/observability/traces/) to observe HTTP 429 responses returned by your Worker when rate limits are exceeded.
* **[Workers Analytics Engine](https://developers.cloudflare.com/analytics/analytics-engine/)** — Add an Analytics Engine binding to your Worker and emit custom data points (for example, a `rate_limited` event) when `limit()` returns `{ success: false }`. This lets you build dashboards and query rate limiting metrics over time.

## Examples

* [@elithrar/workers-hono-rate-limit ↗](https://github.com/elithrar/workers-hono-rate-limit) — Middleware that lets you easily add rate limits to routes in your [Hono ↗](https://hono.dev/) application.
* [@hono-rate-limiter/cloudflare ↗](https://github.com/rhinobase/hono-rate-limiter) — Middleware that lets you easily add rate limits to routes in your [Hono ↗](https://hono.dev/) application, with multiple data stores to choose from.
* [hono-cf-rate-limit ↗](https://github.com/bytaesu/hono-cf-rate-limit) — Middleware for Hono applications that applies rate limiting in Cloudflare Workers, powered by Wrangler’s built-in features.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/workers/","name":"Workers"}},{"@type":"ListItem","position":3,"item":{"@id":"/workers/runtime-apis/","name":"Runtime APIs"}},{"@type":"ListItem","position":4,"item":{"@id":"/workers/runtime-apis/bindings/","name":"Bindings (env)"}},{"@type":"ListItem","position":5,"item":{"@id":"/workers/runtime-apis/bindings/rate-limit/","name":"Rate Limiting"}}]}
```
