---
schema_version: "1"
id: 91504ce3a75b7b5a387db5a78f4ba943129a380de6a78ae544bca7428b95fb5f
title: Rate Limiting Policy
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/gateway/latest/policies-included-rate-limiting.md
canonical_url: https://docs.mulesoft.com/gateway/latest/policies-included-rate-limiting
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 65fe77d75655e4e45a4d9c37c2a9762202f2ae2dccaf05bb52cbe5ab824d6f3f
description: MuleSoft Documentation Site
release: "1.14"
latest: true
---
---
product: Omni Gateway
version: 1.14
is-latest-version: true
keywords: rate limiting, api gateway, flex gateway, gateway, policy
---

# Rate Limiting Policy

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

<table><colgroup><col> <col></colgroup><tbody><tr><td><p><strong>Policy name</strong></p></td><td><div><div><p>Rate Limiting</p></div></div></td></tr><tr><td><p><strong>Summary</strong></p></td><td><div><div><p>Monitors access to an API by defining the maximum number of requests processed within a period of time</p></div></div></td></tr><tr><td><p><strong>Category</strong></p></td><td><div><div><p>Quality of Service</p></div></div></td></tr><tr><td><p><strong>First Omni Gateway version available</strong></p></td><td><div><div><p>v1.2.0</p></div></div></td></tr><tr><td><p><strong>Release Notes</strong></p></td><td><div><div><p><a href="https://docs.mulesoft.com/release-notes/gateway/policies/rate-limiting-release-notes">Rate Limiting</a></p></div></div></td></tr><tr><td rowspan="4"><p><strong>Returned Status Codes</strong></p></td><td><div><div><p>429 - Quota exceeded, requests are blocked until the current window finishes</p></div></div></td></tr></tbody></table>

## Summary

The Rate Limiting policy enables you to control the incoming traffic to an API by limiting the
number of requests that the API can receive within a given period of time. After the limit is
reached, the policy rejects all requests, thereby avoiding any additional load on the backend API.

When you configure the Rate Limiting policy, you can specify any number of pairs of quota (number of
requests) and time window (time period) values.

> [!NOTE] A Rate Limiting policy applied to an Omni Gateway API is scoped to replicas, not the
> gateway.

## Configuring Policy Parameters

### Omni Gateway Local Mode

When you apply the policy via declarative configuration files, Refer to the following policy
definition and table of parameters:

\- policyRef: name: rate-limiting-flex config: rateLimits: <array> // REQUIRED - maximumRequests:
<int> // REQUIRED timePeriodInMilliseconds: <int> // REQUIRED keySelector: <string> // OPTIONAL
exposeHeaders: <bool> // OPTIONAL, default: false clusterizable: <bool> // OPTIONAL, default: true

<table><colgroup><col> <col> <col> <col></colgroup><thead><tr><th>Parameter</th><th>Required or Optional</th><th>Default Value</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>rateLimits</code></p></div></div></td><td><div><div><p>Required</p></div></div></td><td><div><div><p>N/A</p></div></div></td><td><div><div><p>An map containing one or more rate limit specifications</p></div></div></td></tr><tr><td><div><div><p><code>rateLimits.maximumRequests</code></p></div></div></td><td><div><div><p>Required</p></div></div></td><td><div><div><p>N/A</p></div></div></td><td><div><div><p>The quota number available per window</p></div></div></td></tr><tr><td><div><div><p><code>rateLimits.timePeriodInMilliseconds</code></p></div></div></td><td><div><div><p>Required</p></div></div></td><td><div><div><p>N/A</p></div></div></td><td><div><div><p>The amount of time (a number) for which the quota is to be applied</p></div></div></td></tr><tr><td><div><div><p><code>keySelector</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>N/A</p></div></div></td><td><div><div><p>DataWeave expression selector key string that creates a group with independent counters for each value resolved by the expression.</p></div><div><p>For example, <code>#[attributes.queryParams['identifier']]</code> creates an independent counter group for requests containing an <code>identifier</code> query parameter.</p></div></div></td></tr><tr><td><div><div><p><code>exposeHeaders</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p><code>false</code></p></div></div></td><td><div><div><p>The boolean option that defines whether to expose the <a href="#response-header">x-ratelimit headers</a> as part of the response</p></div></div></td></tr><tr><td><div><div><p><code>clusterizable</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p><code>true</code></p></div></div></td><td><div><div><p>Distributed: When enabled, the quota is shared among all Omni Gateway replicas. Distributed rate limiting requires shared storage to be enabled.</p></div></div></td></tr><tr><td><div><div><p>blockOnUnknownQuota</p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p><code>true</code></p></div></div></td><td><div><div><p>For policies using distributed rate limiting (<code>clusterizable</code>), block requests if the policy can’t retrieve the quota from shared storage. If <code>false</code> and the quota can’t be retrieved, no rate limiting is applied.</p></div></div></td></tr></tbody></table>

> [!NOTE] If you enable the distributed rate limiting, the policy resizes time windows under 10
> seconds linearly. For example, if you configure a maximum of 10 requests per 5 seconds, the policy
> resizes that window to a maximum of 20 requests per 10 seconds.

#### Resource Configuration Example

The following example defines a rate limit of three requests every six seconds:

\- policyRef: name: rate-limiting-flex config: rateLimits: - maximumRequests: 3
timePeriodInMilliseconds: 6000 keySelector: "#\[attributes.method\]" exposeHeaders: true
clusterizable: false

The `#[attributes.method]` DataWeave expression creates one group for each available method in HTTP,
for example, the policy rate-limits GET requests independently of POST requests.

#### Distributed Rate Limit Resource Configuration Example

Distributed Rate Limit requires shared storage to be enabled. Configure either
[distributed shared storage](https://docs.mulesoft.com/gateway/latest/conn-distributed-shared-storage-config) or
[Redis shared storage](https://docs.mulesoft.com/gateway/latest/conn-shared-storage-config).

\--- apiVersion: gateway.mulesoft.com/v1alpha1 kind: Configuration metadata: name:
shared-storage-redis spec: sharedStorage: redis: address: redis:6379 user: user password: pass DB: 1

---

- policyRef: name: rate-limiting-flex config: rateLimits: - maximumRequests: 3
  timePeriodInMilliseconds: 6000 keySelector: "#\[attributes.method\]" exposeHeaders: true
  clusterizable: true

### Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Parameter</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><div><div><p>Identifier</p></div></div></td><td><div><div><p>The selector key using a DataWeave or regular String</p></div></div></td><td><div><div><p><code>#[attributes.method]</code> creates one group for each available method in HTTP, for example, the policy rate-limits GET requests independently from POST requests.</p></div></div></td></tr><tr><td><div><div><p>Number of Reqs</p></div></div></td><td><div><div><p>The quota available per window</p></div></div></td><td><div><div><p>A positive number</p></div></div></td></tr><tr><td><div><div><p>Time Period</p></div></div></td><td><div><div><p>The amount of time for which the quota is to be applied</p></div></div></td><td><div><div><p>A positive number</p></div></div></td></tr><tr><td><div><div><p>Time Unit</p></div></div></td><td><div><div><p>The time in milliseconds, seconds, minutes, or hours</p></div></div></td><td><div><div><p>Minutes</p></div></div></td></tr><tr><td><div><div><p>Distributed</p></div></div></td><td><div><div><p>When enabled, the quota is shared among all Omni Gateway replicas. Distributed rate limiting requires shared storage to be enabled.</p></div></div></td><td><div><div><p>checked or unchecked</p></div></div></td></tr><tr><td><div><div><p>Expose Headers</p></div></div></td><td><div><div><p>The option that defines whether to expose the <a href="#response-header">x-ratelimit headers</a> as part of the response</p></div></div></td><td><div><div><p>checked or unchecked</p></div></div></td></tr><tr><td><div><div><p>Block on unknown quota</p></div></div></td><td><div><div><p>For policies using distributed rate limiting, block requests if the policy cannot retrieve the quota from shared storage. If not enabled and the quota can’t be retrieved, no rate limiting is applied.</p></div></div></td><td><div><div><p>checked or unchecked</p></div></div></td></tr></tbody></table>

> [!NOTE] If you enable the distributed rate limiting, the policy resizes time windows under 10
> seconds linearly. For example, if you configure a maximum of 10 requests per 5 seconds, the policy
> resizes that window to a maximum of 20 requests per 10 seconds.

## How This Policy Works

The Rate Limiting policy monitors the number of requests made in the current window (the available
quota), allowing the requests to reach the backend only if the available quota is greater than zero.

You can configure the policy for multiple groups of requests by using identifiers in the policy
configuration. Each group has a separate available quota for its window.

To understand how the Rate Limiting policy works, consider an example in which the configuration of
3 requests every 10 seconds allows or restricts incoming requests, based on the quota available in
that window:

![A timeline of accepted and rejected requests in two time windows](/mulesoft/current/en-us/gateway/latest/_images/rate-limiting-generic-example.png)

In the first window, because the quota is reached with the third request, all subsequent requests
are rejected until the window closes. In the second window, only two of the three requests are
processed and the quota remaining is dropped after the window time has elapsed.

An accepted request passes through the API to the backend. Conversely, a rejected request displays
429 status for HTTP (or either 400 or 500 if the API is WSDL) and does not reach the backend.

A rejected request on the other hand, displays a “429 status for HTTP, ” (or either 400 or 500 if
the API is WSDL) and does not reach the backend.

## Examples

Consider the previously described configuration of 3 requests every 10 seconds and how it works when
the Rate Limiting policy is configured for clusters and uses identifiers.

### Configuring Identifiers by Using Regular Strings

When you use the UI to add identifiers to the policy configuration, you can define groups of
requests. The configured limits apply independently to each group. You can also use the identifier
`#[attributes.method]` for one bucket per HTTP method in your Rate Limiting policy configuration.

An `Identifier` in the UI is a non-obligatory parameter. By default, the `Identifier` has no value.
Based on whether you accept the default or provide a value, the policy performs in the following
ways:

- Not configured (default)

  The Rate Limiting quota applies to every request per bucket or group.

- Configured for an obligatory HTTP header

  Each header has its own quota. Header values are case-sensitive. Quotas are created using the
  _lazy creation_ strategy.

- Configured for a non-obligatory HTTP header

  Custom header, payload, query parameter, or expression values each have their own quotas.

  The identifier, if not sent in the request, defaults to an empty value, having its own quota. This
  behavior allows the Rate Limiting policy to be applied to an API consumed by uncontrolled clients,
  and at the same time accommodates special buckets for the clients sending the identifier.

The following example shows the order of events that occur over a period of time using the
identifier `#[attributes.method]` for a limit of 3 requests every 10 seconds:

![A line chart illustrating the acceptance and rejection of GET and POST requests over time](/mulesoft/current/en-us/gateway/latest/_images/rate-limiting-configure-identifiers-example.png)

In the example:

- Every HTTP method is allowed 3 requests every 10 seconds (in this example, only GET and POST
  requests are made to the API).

- The Rate Limiting policy works in a fixed-window fashion.

  For more information, see the fixed-window size bracket in the diagram.

- The window start times are independent.

- The engine uses a _lazy creation_ strategy that spools a rate-limiting algorithm whenever the
  first request for a method is received.

### Configuring Identifiers by Using DataWeave Expressions

The rate-limiting engine, which is HTTP agnostic, depends solely on the resolution of the DataWeave
expression. You can alter the `Identifier` expression in the UI to cover complex rate-limiting
scenarios.

For example, you can configure a Rate Limiting policy with an identifier that uses one bucket for
all Class A and Class C LAN requests and another bucket for everything else. The following image
illustrates the second bucket in the previous sentence, which corresponds to 3 requests per 10
seconds quota with the DataWeave expression `#[attributes.queryParam[‘customIdentifier’]]` as the
policy identifier:

![A timeline that displays both accepted and rejected requests, organized by time intervals](/mulesoft/current/en-us/gateway/latest/_images/rate-limiting-configure-identifiers-dataweave.png)

In the example:

- All requests without the identifier are resolved to the empty identifier and therefore use a
  single rate-limiting algorithm.

- Each different identifier uses a different bucket, each bucket with its own independent quota.

This configuration creates a false or a true bucket that corresponds to the locality of the IP that
made the request. The `false` and `true` values correspond to the domain of boolean values and not
HTTP.

Nevertheless, the policy works correctly because the engine treats the resolved expression as a
String. In this case, the value is automatically cast from Boolean to String. You can explicitly
define casting in DataWeave by adding `output text/plain ---` to your script.

> [!NOTE] The HTTP RFC header names are case-insensitive. Anypoint Connector for MuleSoft HTTP
> changes header names to lowercase characters. However, the DataWeave key is case-sensitive.
> Therefore, when creating the `Identifier` expression, remember to reference headers in lowercase.

### Configuring Unbound Identifier Sets

Every identifier result has one algorithm. You must carefully create a DataWeave expression that
does not return an unbound or a very large co-domain, which requires hosting the same number of
algorithms in memory (at least a request for every possible identifier has to be made, because
algorithms are created using the _lazy creation_ strategy).

For example, suppose the DataWeave expression uses the IP address as the identifier in an Omni
Gateway instance that is public to the internet. If every public IPv4 IP on the internet makes a
request to this instance, there will be 3,706,452,992 algorithms running in a single instance.

At an average of 250 bytes per algorithm, this amounts to approximately 1 terabyte in rate-limit
algorithms. Therefore, use a DataWeave expression that resolves to a finite number of identifier to
keep the resulting set as small as possible.

## FAQ

**When does the window start?**

The window starts with the first request after the policy is successfully applied.

**What type of window does the algorithm use?**

It uses a fixed window.

**What happens when the quota is exhausted?**

The algorithm is created on demand, when the first request is received. This event fixes the time
window. Each request consumes the request quota from the current window until the time expires.

When the request quota is exhausted, the Rate Limiting policy rejects the request. When the time
window closes, the request quota is reset and a new window of the same fixed size starts.

**What happens if I define multiple limits?**

The policy creates one algorithm for each Limit with the request quota per time window
configuration. Therefore, when multiple limits are configured, every algorithm must have its own
available quota within the current window for the request to be accepted.

**What does each response header mean?**

Each response header has information about the current state of the request:

- X-Ratelimit-Remaining: The amount of available quota

- X-Ratelimit-Limit: The maximum available requests per window

- X-Ratelimit-Reset: The remaining time, in milliseconds, until a new window starts

By default, the X-RateLimit headers are disabled in the response. You can enable these headers by
selecting **Expose Headers** when you configure the policy.

**When should I use Rate Limiting instead of Rate-Limiting SLA or Spike Control?**

Use Rate Limiting and **Rate-Limiting SLA** policies for accountability and to enforce a hard limit
to a group (using the identifier in Rate Limiting) or to a client application (using **Rate-Limiting
SLA**). If you want to protect your backend, use the **Spike Control** policy instead.
