> For the complete documentation index, see [llms.txt](https://docs.digitalapi.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.digitalapi.ai/api-gateway/plugin-reference/plugins-traffic.md).

# Traffic plugins

Plugins in this category shape how traffic moves through the gateway: rate limits, concurrency caps, circuit breakers, request buffering, IP allow- and deny-lists. Use them to protect upstreams from overload and to enforce per-consumer or per-route quotas. The catalogue ships 13 Traffic plugins.

{% hint style="info" %}
**In this category:** [`api-breaker`](#api-breaker), [`api-product-enforcer`](#api-product-enforcer), [`client-control`](#client-control), [`limit-conn`](#limit-conn), [`limit-count`](#limit-count), [`limit-req`](#limit-req), [`proxy-cache`](#proxy-cache), [`proxy-control`](#proxy-control), [`proxy-mirror`](#proxy-mirror), [`request-id`](#request-id), [`request-validation`](#request-validation), [`traffic-split`](#traffic-split), [`workflow`](#workflow)
{% endhint %}

### `api-breaker`

The `api-breaker` Plugin implements circuit breaker functionality to protect Upstream services.

{% hint style="info" %}
**Priority** `1005` · **Category** Traffic · **Required** `break_response_code`
{% endhint %}

<details>

<summary>Configuration and details</summary>

:::note

Whenever the Upstream service responds with a status code from the configured `unhealthy.http_statuses` list for the configured `unhealthy.failures` number of times, the Upstream service will be considered unhealthy.

The request is then retried in 2, 4, 8, 16 ... seconds until the `max_breaker_sec`.

In an unhealthy state, if the Upstream service responds with a status code from the configured list `healthy.http_statuses` for `healthy.successes` times, the service is considered healthy again.

:::

| Name                     | Type            | Required | Default | Valid values                                                      | Description                                                                                                                                                                                                                                                                         |
| ------------------------ | --------------- | -------- | ------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| break\_response\_code    | integer         | True     |         | \[200, ..., 599]                                                  | HTTP error code to return when Upstream is unhealthy.                                                                                                                                                                                                                               |
| break\_response\_body    | string          | False    |         |                                                                   | Body of the response message to return when Upstream is unhealthy.                                                                                                                                                                                                                  |
| break\_response\_headers | array\[object]  | False    |         | \[{"key":"header\_name","value":"can contain gateway variables"}] | Headers of the response message to return when Upstream is unhealthy. Can only be configured when the `break_response_body` attribute is configured. The values can contain Helix variables. For example, we can use `{"key":"X-Client-Addr","value":"$remote_addr:$remote_port"}`. |
| max\_breaker\_sec        | integer         | False    | 300     | >=3                                                               | Maximum time in seconds for circuit breaking.                                                                                                                                                                                                                                       |
| unhealthy.http\_statuses | array\[integer] | False    | \[500]  | \[500, ..., 599]                                                  | Status codes of Upstream to be considered unhealthy.                                                                                                                                                                                                                                |
| unhealthy.failures       | integer         | False    | 3       | >=1                                                               | Number of failures within a certain period of time for the Upstream service to be considered unhealthy.                                                                                                                                                                             |
| healthy.http\_statuses   | array\[integer] | False    | \[200]  | \[200, ..., 499]                                                  | Status codes of Upstream to be considered healthy.                                                                                                                                                                                                                                  |
| healthy.successes        | integer         | False    | 3       | >=1                                                               | Number of consecutive healthy requests for the Upstream service to be considered healthy.                                                                                                                                                                                           |

**Sample configuration**

Minimal, return `502` while the Upstream is considered unhealthy:

```json
{
  "api-breaker": {
    "break_response_code": 502
  }
}
```

Custom response body and header returned during circuit breaking:

```json
{
  "api-breaker": {
    "break_response_code": 503,
    "break_response_body": "Service temporarily unavailable",
    "break_response_headers": [
      { "key": "Content-Type", "value": "text/plain" },
      { "key": "X-Client-Addr", "value": "$remote_addr:$remote_port" }
    ]
  }
}
```

Tuned health thresholds and a longer maximum break window:

```json
{
  "api-breaker": {
    "break_response_code": 502,
    "max_breaker_sec": 600,
    "unhealthy": {
      "http_statuses": [500, 502, 503],
      "failures": 5
    },
    "healthy": {
      "http_statuses": [200, 206],
      "successes": 2
    }
  }
}
```

</details>

### `api-product-enforcer`

The `api-product-enforcer` plugin is part of the Helix API Products model. It authorizes the calling application against its subscribed API products and enforces the product quota. It runs in the **access** phase **after a supported authentication plugin** has authenticated the caller and selected the matching product, which the enforcer reads from the request context (`ctx.helix.helix_product`). [`helix-auth`](/api-gateway/plugin-reference/plugins-authentication.md#helix-auth) in validate mode is the usual choice.

The quota is counted per **app** or per **developer**, following the product's **Quota scope** (see [API products](/api-gateway/api-gateway/api-products.md#quota)): *app* keeps a separate allowance for each app, *developer* shares one allowance across all of a developer's apps.

{% hint style="warning" %}
**Enable a supported authentication plugin first.** The enforcer reads the product context that the authentication step writes on the request. Without a supported authentication plugin (any that resolves the caller and product, such as `helix-auth`) attached and running earlier on the same route or API, the enforcer has no product to authorize against. The portal requires one at the same scope before you can add the enforcer.
{% endhint %}

{% hint style="info" %}
**Priority** `2399` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

| Name           | Type   | Required | Default                | Valid values                  | Description                                                                                                   |
| -------------- | ------ | -------- | ---------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------- |
| ctx\_namespace | string | False    | `api_product_enforcer` |                               | Namespace under `ctx.helix` where quota ctx fields are stored.                                                |
| error\_policy  | string | False    | `fail_close`           | \["fail\_open","fail\_close"] | `fail_close` rejects the request when product data cannot be resolved; `fail_open` lets the request continue. |

**Sample configuration**

Minimal, enforce the product quota and reject when the product context cannot be resolved (the default):

```json
{
  "api-product-enforcer": {
    "error_policy": "fail_close"
  }
}
```

Let requests continue when product data cannot be resolved:

```json
{
  "api-product-enforcer": {
    "error_policy": "fail_open"
  }
}
```

Store quota fields under a custom namespace:

```json
{
  "api-product-enforcer": {
    "ctx_namespace": "product_quota",
    "error_policy": "fail_close"
  }
}
```

</details>

### `client-control`

The `client-control` Plugin can be used to dynamically control how the gateway handles a client request, by setting the max size of the request body.

{% hint style="info" %}
**Priority** `22000` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

:::info IMPORTANT

This Plugin requires Helix to run on Helix-Runtime. See helix-build-tools for more info.

:::

| Name            | Type    | Required | Valid values | Description                                                                                                                                                                                                                          |
| --------------- | ------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| max\_body\_size | integer | False    | \[0,...]     | Set the maximum limit for the client request body and dynamically adjust the size of `client_max_body_size`, measured in bytes. If you set the `max_body_size` to 0, then the size of the client's request body will not be checked. |

**Sample configuration**

Cap the client request body at 1 MB (bytes):

```json
{
  "client-control": {
    "max_body_size": 1048576
  }
}
```

Do not check the request body size at all:

```json
{
  "client-control": {
    "max_body_size": 0
  }
}
```

</details>

### `limit-conn`

The `limit-conn` Plugin limits the rate of requests by the number of concurrent connections. Requests exceeding the threshold will be delayed or rejected based on the configuration, ensuring controlled resource usage and preventing overload.

{% hint style="info" %}
**Priority** `1003` · **Category** Traffic · **Required** `conn`, `burst`, `default_conn_delay`, `key`
{% endhint %}

<details>

<summary>Configuration and details</summary>

| Name                        | Type           | Required | Default      | Valid values                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| --------------------------- | -------------- | -------- | ------------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| conn                        | integer        | True     |              | > 0                                | The maximum number of concurrent requests allowed. Requests exceeding the configured limit and below `conn + burst` will be delayed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| burst                       | integer        | True     |              | >= 0                               | The number of excessive concurrent requests allowed to be delayed per second. Requests exceeding the limit will be rejected immediately.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| default\_conn\_delay        | number         | True     |              | > 0                                | Processing latency allowed in seconds for concurrent requests exceeding `conn + burst`, which can be dynamically adjusted based on `only_use_default_delay` setting.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| only\_use\_default\_delay   | boolean        | False    | false        |                                    | If false, delay requests proportionally based on how much they exceed the `conn` limit. The delay grows larger as congestion increases. For instance, with `conn` being `5`, `burst` being `3`, and `default_conn_delay` being `1`, 6 concurrent requests would result in a 1-second delay, 7 requests a 2-second delay, 8 requests a 3-second delay, and so on, until the total limit of `conn + burst` is reached, beyond which requests are rejected. If true, use `default_conn_delay` to delay all excessive requests within the `burst` range. Requests beyond `conn + burst` are rejected immediately. For instance, with `conn` being `5`, `burst` being `3`, and `default_conn_delay` being `1`, 6, 7, or 8 concurrent requests are all delayed by exactly 1 second each. |
| key\_type                   | string         | False    | var          | \["var","var\_combination"]        | The type of key. If the `key_type` is `var`, the `key` is interpreted a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| key                         | string         | False    | remote\_addr |                                    | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`.                                                                                                                                                                                                                                                                             |
| key\_ttl                    | integer        | False    | 3600         |                                    | The TTL of the Redis key in seconds. Used when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| rejected\_code              | integer        | False    | 503          | \[200,...,599]                     | The HTTP status code returned when a request is rejected for exceeding the threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| rejected\_msg               | string         | False    |              | non-empty                          | The response body returned when a request is rejected for exceeding the threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| allow\_degradation          | boolean        | False    | false        |                                    | If true, allow Helix to continue handling requests without the Plugin when the Plugin or its dependencies become unavailable.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| policy                      | string         | False    | local        | \["local","redis","redis-cluster"] | The policy for rate limiting counter. If it is `local`, the counter is stored in memory locally. If it is `redis`, the counter is stored on a Redis instance. If it is `redis-cluster`, the counter is stored in a Redis cluster.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| redis\_host                 | string         | False    |              |                                    | The address of the Redis node. Required when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| redis\_port                 | integer        | False    | 6379         | \[1,...]                           | The port of the Redis node when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| redis\_username             | string         | False    |              |                                    | The username for Redis if Redis ACL is used. If you use the legacy authentication method `requirepass`, configure only the `redis_password`. Used when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| redis\_password             | string         | False    |              |                                    | The password of the Redis node when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| redis\_ssl                  | boolean        | False    | false        |                                    | If true, use SSL to connect to Redis cluster when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| redis\_ssl\_verify          | boolean        | False    | false        |                                    | If true, verify the server SSL certificate when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| redis\_database             | integer        | False    | 0            | >= 0                               | The database number in Redis when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| redis\_timeout              | integer        | False    | 1000         | \[1,...]                           | The Redis timeout value in milliseconds when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| redis\_keepalive\_timeout   | integer        | False    | 10000        | ≥ 1000                             | Keepalive timeout in milliseconds for redis when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| redis\_keepalive\_pool      | integer        | False    | 100          | ≥ 1                                | Keepalive pool size for redis when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| redis\_cluster\_nodes       | array\[string] | False    |              |                                    | The list of the Redis cluster nodes with at least two addresses. Required when policy is redis-cluster.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| redis\_cluster\_name        | string         | False    |              |                                    | The name of the Redis cluster. Required when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| redis\_cluster\_ssl         | boolean        | False    | false        |                                    | If true, use SSL to connect to Redis cluster when `policy` is                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| redis\_cluster\_ssl\_verify | boolean        | False    | false        |                                    | If true, verify the server SSL certificate when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

**Sample configuration**

Minimal, limit concurrent connections per client address with the local (in-memory) counter:

```json
{
  "limit-conn": {
    "conn": 20,
    "burst": 10,
    "default_conn_delay": 0.5,
    "key": "remote_addr"
  }
}
```

Key on a header combination and return a custom rejection code and message:

```json
{
  "limit-conn": {
    "conn": 20,
    "burst": 10,
    "default_conn_delay": 0.5,
    "key_type": "var_combination",
    "key": "$http_custom_a $http_custom_b",
    "rejected_code": 429,
    "rejected_msg": "Too many concurrent requests"
  }
}
```

Redis policy (counter shared across gateway nodes):

```json
{
  "limit-conn": {
    "conn": 20,
    "burst": 10,
    "default_conn_delay": 0.5,
    "key": "remote_addr",
    "policy": "redis",
    "redis_host": "127.0.0.1",
    "redis_port": 6379,
    "redis_password": "my-redis-password",
    "redis_timeout": 1000
  }
}
```

Redis cluster policy (shared counter across a Redis cluster):

```json
{
  "limit-conn": {
    "conn": 20,
    "burst": 10,
    "default_conn_delay": 0.5,
    "key": "remote_addr",
    "policy": "redis-cluster",
    "redis_cluster_nodes": [
      "127.0.0.1:7000",
      "127.0.0.1:7001"
    ],
    "redis_cluster_name": "helix-limit-cluster",
    "redis_password": "my-redis-password"
  }
}
```

</details>

### `limit-count`

The `limit-count` plugin uses a fixed window algorithm to limit the rate of requests by the number of requests within a given time interval. Requests exceeding the configured quota will be rejected.

{% hint style="info" %}
**Priority** `1002` · **Category** Traffic · **Required** `count`, `time_window`
{% endhint %}

<details>

<summary>Configuration and details</summary>

You may see the following rate limiting headers in the response:

* `X-RateLimit-Limit`: the total quota
* `X-RateLimit-Remaining`: the remaining quota
* `X-RateLimit-Reset`: number of seconds left for the counter to reset

| Name                        | Type           | Required | Default      | Valid values                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| --------------------------- | -------------- | -------- | ------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| count                       | integer        | True     |              | > 0                                    | The maximum number of requests allowed within a given time interval.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| time\_window                | integer        | True     |              | > 0                                    | The time interval corresponding to the rate limiting `count` in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| key\_type                   | string         | False    | var          | \["var","var\_combination","constant"] | The type of key. If the `key_type` is `var`, the `key` is interpreted a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. If the `key_type` is `constant`, the `key` is interpreted as a constant.                                                                                                                                                                                                                                                                                                                            |
| key                         | string         | False    | remote\_addr |                                        | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`. If the `key_type` is `constant`, the `key` is interpreted as a constant value. |
| rejected\_code              | integer        | False    | 503          | \[200,...,599]                         | The HTTP status code returned when a request is rejected for exceeding the threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| rejected\_msg               | string         | False    |              | non-empty                              | The response body returned when a request is rejected for exceeding the threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| policy                      | string         | False    | local        | \["local","redis","redis-cluster"]     | The policy for rate limiting counter. If it is `local`, the counter is stored in memory locally. If it is `redis`, the counter is stored on a Redis instance. If it is `redis-cluster`, the counter is stored in a Redis cluster.                                                                                                                                                                                                                                                                                                                                                     |
| allow\_degradation          | boolean        | False    | false        |                                        | If true, allow Helix to continue handling requests without the plugin when the plugin or its dependencies become unavailable.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| show\_limit\_quota\_header  | boolean        | False    | true         |                                        | If true, include `X-RateLimit-Limit` to show the total quota and `X-RateLimit-Remaining` to show the remaining quota in the response header.                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| group                       | string         | False    |              | non-empty                              | The `group` ID for the plugin, such that routes of the same `group` can share the same rate limiting counter.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| redis\_host                 | string         | False    |              |                                        | The address of the Redis node. Required when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| redis\_port                 | integer        | False    | 6379         | \[1,...]                               | The port of the Redis node when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| redis\_username             | string         | False    |              |                                        | The username for Redis if Redis ACL is used. If you use the legacy authentication method `requirepass`, configure only the `redis_password`. Used when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                           |
| redis\_password             | string         | False    |              |                                        | The password of the Redis node when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| redis\_ssl                  | boolean        | False    | false        |                                        | If true, use SSL to connect to Redis cluster when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| redis\_ssl\_verify          | boolean        | False    | false        |                                        | If true, verify the server SSL certificate when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| redis\_database             | integer        | False    | 0            | >= 0                                   | The database number in Redis when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| redis\_timeout              | integer        | False    | 1000         | \[1,...]                               | The Redis timeout value in milliseconds when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| redis\_keepalive\_timeout   | integer        | False    | 10000        | ≥ 1000                                 | Keepalive timeout in milliseconds for redis when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| redis\_keepalive\_pool      | integer        | False    | 100          | ≥ 1                                    | Keepalive pool size for redis when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| redis\_cluster\_nodes       | array\[string] | False    |              |                                        | The list of the Redis cluster nodes with at least two addresses. Required when policy is redis-cluster.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| redis\_cluster\_name        | string         | False    |              |                                        | The name of the Redis cluster. Required when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| redis\_cluster\_ssl         | boolean        | False    | false        |                                        | If true, use SSL to connect to Redis cluster when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| redis\_cluster\_ssl\_verify | boolean        | False    | false        |                                        | If true, verify the server SSL certificate when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

**Sample configuration**

Minimal, allow 100 requests per 60 seconds with the local (in-memory) counter:

```json
{
  "limit-count": {
    "count": 100,
    "time_window": 60
  }
}
```

Share one counter across routes of the same group and key on a constant so all clients share the quota:

```json
{
  "limit-count": {
    "count": 1000,
    "time_window": 60,
    "key_type": "constant",
    "key": "api-quota",
    "group": "public-api",
    "rejected_code": 429,
    "rejected_msg": "Rate limit exceeded"
  }
}
```

Redis policy (counter shared across gateway nodes):

```json
{
  "limit-count": {
    "count": 100,
    "time_window": 60,
    "policy": "redis",
    "redis_host": "127.0.0.1",
    "redis_port": 6379,
    "redis_password": "my-redis-password",
    "redis_database": 0,
    "redis_timeout": 1000
  }
}
```

Redis cluster policy (shared counter across a Redis cluster):

```json
{
  "limit-count": {
    "count": 100,
    "time_window": 60,
    "policy": "redis-cluster",
    "redis_cluster_nodes": [
      "127.0.0.1:7000",
      "127.0.0.1:7001"
    ],
    "redis_cluster_name": "helix-limit-cluster",
    "redis_password": "my-redis-password",
    "redis_cluster_ssl": true,
    "redis_cluster_ssl_verify": true
  }
}
```

</details>

### `limit-req`

The `limit-req` Plugin uses the [leaky bucket](https://en.wikipedia.org/wiki/Leaky_bucket) algorithm to rate limit the number of the requests and allow for throttling.

{% hint style="info" %}
**Priority** `1001` · **Category** Traffic · **Required** `rate`, `burst`, `key`
{% endhint %}

<details>

<summary>Configuration and details</summary>

| Name                        | Type           | Required | Default      | Valid values                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| --------------------------- | -------------- | -------- | ------------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| rate                        | integer        | True     |              | > 0                                  | The maximum number of requests allowed per second. Requests exceeding the rate and below burst will be delayed.                                                                                                                                                                                                                                                                                                                                                                                        |
| burst                       | integer        | True     |              | >= 0                                 | The number of requests allowed to be delayed per second for throttling. Requests exceeding the rate and burst will get rejected.                                                                                                                                                                                                                                                                                                                                                                       |
| key\_type                   | string         | False    | var          | \["var", "var\_combination"]         | The type of key. If the `key_type` is `var`, the `key` is interpreted a variable. If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables.                                                                                                                                                                                                                                                                                                                      |
| key                         | string         | True     | remote\_addr |                                      | The key to count requests by. If the `key_type` is `var`, the `key` is interpreted a variable. The variable does not need to be prefixed by a dollar sign (`$`). If the `key_type` is `var_combination`, the `key` is interpreted as a combination of variables. All variables should be prefixed by dollar signs (`$`). For example, to configure the `key` to use a combination of two request headers `custom-a` and `custom-b`, the `key` should be configured as `$http_custom_a $http_custom_b`. |
| rejected\_code              | integer        | False    | 503          | \[200,...,599]                       | The HTTP status code returned when a request is rejected for exceeding the threshold.                                                                                                                                                                                                                                                                                                                                                                                                                  |
| rejected\_msg               | string         | False    |              | non-empty                            | The response body returned when a request is rejected for exceeding the threshold.                                                                                                                                                                                                                                                                                                                                                                                                                     |
| nodelay                     | boolean        | False    | false        |                                      | If true, do not delay requests within the burst threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| allow\_degradation          | boolean        | False    | false        |                                      | If true, allow Helix to continue handling requests without the Plugin when the Plugin or its dependencies become unavailable.                                                                                                                                                                                                                                                                                                                                                                          |
| policy                      | string         | False    | local        | \["local", "redis", "redis-cluster"] | The policy for rate limiting counter. If it is `local`, the counter is stored in memory locally. If it is `redis`, the counter is stored on a Redis instance. If it is `redis-cluster`, the counter is stored in a Redis cluster.                                                                                                                                                                                                                                                                      |
| redis\_host                 | string         | False    |              |                                      | The address of the Redis node. Required when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| redis\_port                 | integer        | False    | 6379         | \[1,...]                             | The port of the Redis node when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| redis\_username             | string         | False    |              |                                      | The username for Redis if Redis ACL is used. If you use the legacy authentication method `requirepass`, configure only the `redis_password`. Used when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                            |
| redis\_password             | string         | False    |              |                                      | The password of the Redis node when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                            |
| redis\_ssl                  | boolean        | False    | false        |                                      | If true, use SSL to connect to Redis cluster when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| redis\_ssl\_verify          | boolean        | False    | false        |                                      | If true, verify the server SSL certificate when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| redis\_database             | integer        | False    | 0            | >= 0                                 | The database number in Redis when `policy` is `redis`.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| redis\_timeout              | integer        | False    | 1000         | \[1,...]                             | The Redis timeout value in milliseconds when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                   |
| redis\_keepalive\_timeout   | integer        | False    | 10000        | ≥ 1000                               | Keepalive timeout in milliseconds for redis when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                               |
| redis\_keepalive\_pool      | integer        | False    | 100          | ≥ 1                                  | Keepalive pool size for redis when `policy` is `redis` or `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| redis\_cluster\_nodes       | array\[string] | False    |              |                                      | The list of the Redis cluster nodes with at least two addresses. Required when policy is redis-cluster.                                                                                                                                                                                                                                                                                                                                                                                                |
| redis\_cluster\_name        | string         | False    |              |                                      | The name of the Redis cluster. Required when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                              |
| redis\_cluster\_ssl         | boolean        | False    | false        |                                      | If true, use SSL to connect to Redis cluster when `policy` is                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| redis\_cluster\_ssl\_verify | boolean        | False    | false        |                                      | If true, verify the server SSL certificate when `policy` is `redis-cluster`.                                                                                                                                                                                                                                                                                                                                                                                                                           |

**Sample configuration**

Minimal, allow 10 requests per second per client address with a burst of 5, using the local (in-memory) counter:

```json
{
  "limit-req": {
    "rate": 10,
    "burst": 5,
    "key": "remote_addr"
  }
}
```

Do not delay bursts, reject immediately once the rate is exceeded:

```json
{
  "limit-req": {
    "rate": 10,
    "burst": 5,
    "key": "remote_addr",
    "nodelay": true,
    "rejected_code": 429,
    "rejected_msg": "Rate limit exceeded"
  }
}
```

Redis policy (counter shared across gateway nodes):

```json
{
  "limit-req": {
    "rate": 10,
    "burst": 5,
    "key": "remote_addr",
    "policy": "redis",
    "redis_host": "127.0.0.1",
    "redis_port": 6379,
    "redis_password": "my-redis-password",
    "redis_timeout": 1000
  }
}
```

Redis cluster policy (shared counter across a Redis cluster):

```json
{
  "limit-req": {
    "rate": 10,
    "burst": 5,
    "key": "remote_addr",
    "policy": "redis-cluster",
    "redis_cluster_nodes": [
      "127.0.0.1:7000",
      "127.0.0.1:7001"
    ],
    "redis_cluster_name": "helix-limit-cluster",
    "redis_password": "my-redis-password"
  }
}
```

</details>

### `proxy-cache`

The `proxy-cache` Plugin provides the capability to cache responses based on a cache key. The Plugin supports both disk-based and memory-based caching options to cache for [GET](https://anything.org/learn/serving-over-http/#get-request), [POST](https://anything.org/learn/serving-over-http/#post-request), and [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) requests.

{% hint style="info" %}
**Priority** `1085` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

Responses can be conditionally cached based on request HTTP methods, response status codes, request header values, and more.

| Name                 | Type            | Required | Default                     | Valid values             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| -------------------- | --------------- | -------- | --------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cache\_strategy      | string          | False    | disk                        | \["disk","memory"]       | Caching strategy. Cache on disk or in memory.                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| cache\_zone          | string          | False    | disk\_cache\_one            |                          | Cache zone used with the caching strategy. The value should match one of the cache zones defined in the [configuration files](#static-configurations) and should correspond to the caching strategy. For example, when using the in-memory caching strategy, you should use an in-memory cache zone.                                                                                                                                                                             |
| cache\_key           | array\[string]  | False    | \["$host", "$request\_uri"] |                          | Key to use for caching. Support gateway variables and constant strings in values. Variables should be prefixed with a `$` sign.                                                                                                                                                                                                                                                                                                                                                  |
| cache\_bypass        | array\[string]  | False    |                             |                          | One or more parameters to parse value from, such that if any of the values is not empty and is not equal to `0`, response will not be retrieved from cache. Support gateway variables and constant strings in values. Variables should be prefixed with a `$` sign.                                                                                                                                                                                                              |
| cache\_method        | array\[string]  | False    | \["GET", "HEAD"]            | \["GET", "POST", "HEAD"] | Request methods of which the response should be cached.                                                                                                                                                                                                                                                                                                                                                                                                                          |
| cache\_http\_status  | array\[integer] | False    | \[200, 301, 404]            | \[200, 599]              | Response HTTP status codes of which the response should be cached.                                                                                                                                                                                                                                                                                                                                                                                                               |
| hide\_cache\_headers | boolean         | False    | false                       |                          | If true, hide `Expires` and `Cache-Control` response headers.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| cache\_control       | boolean         | False    | false                       |                          | If true, comply with `Cache-Control` behavior in the HTTP specification. Only valid for in-memory strategy.                                                                                                                                                                                                                                                                                                                                                                      |
| no\_cache            | array\[string]  | False    |                             |                          | One or more parameters to parse value from, such that if any of the values is not empty and is not equal to `0`, response will not be cached. Support gateway variables and constant strings in values. Variables should be prefixed with a `$` sign.                                                                                                                                                                                                                            |
| cache\_ttl           | integer         | False    | 300                         | >=1                      | Cache time to live (TTL) in seconds when caching in memory. To adjust the TTL when caching on disk, update `cache_ttl` in the [configuration files](#static-configurations). The TTL value is evaluated in conjunction with the values in the response headers [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) and [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) received from the Upstream service. |

**Sample configuration**

Minimal, cache on disk with the default cache zone and defaults:

```json
{
  "proxy-cache": {
    "cache_strategy": "disk",
    "cache_zone": "disk_cache_one"
  }
}
```

In-memory caching with a custom TTL and `Cache-Control` compliance:

```json
{
  "proxy-cache": {
    "cache_strategy": "memory",
    "cache_zone": "memory_cache",
    "cache_ttl": 120,
    "cache_control": true
  }
}
```

Conditional caching by method, status code, and a custom cache key, with a bypass parameter:

```json
{
  "proxy-cache": {
    "cache_key": ["$host", "$request_uri", "$http_accept"],
    "cache_method": ["GET", "HEAD"],
    "cache_http_status": [200, 301],
    "cache_bypass": ["$arg_nocache"],
    "hide_cache_headers": true
  }
}
```

</details>

### `proxy-control`

The proxy-control Plugin dynamically controls the gateway's proxy behavior.

{% hint style="info" %}
**Priority** `21990` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

:::info IMPORTANT

This Plugin requires Helix to run on Helix-Runtime. See helix-build-tools for more info.

:::

| Name               | Type    | Required | Default | Description                                                                              |
| ------------------ | ------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
| request\_buffering | boolean | False    | true    | When set to `true`, the Plugin dynamically sets the `proxy_request_buffering` directive. |

**Sample configuration**

Disable request buffering so the Upstream receives the body as it streams in:

```json
{
  "proxy-control": {
    "request_buffering": false
  }
}
```

</details>

### `proxy-mirror`

The `proxy-mirror` Plugin duplicates ingress traffic to Helix and forwards them to a designated upstream, without interrupting the regular services. You can configure the Plugin to mirror all traffic or only a portion. The mechanism benefits a few use cases, including troubleshooting, security inspection, analytics, and more.

{% hint style="info" %}
**Priority** `1010` · **Category** Traffic · **Required** `host`
{% endhint %}

<details>

<summary>Configuration and details</summary>

Note that Helix ignores any response from the Upstream host receiving mirrored traffic.

| Name               | Type   | Required | Default | Valid values           | Description                                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ------ | -------- | ------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| host               | string | True     |         |                        | Address of the host to forward the mirrored traffic to. The address should contain the scheme but without the path, such as `http://127.0.0.1:8081`.                                                                                                                                                                                                               |
| path               | string | False    |         |                        | Path of the host to forward the mirrored traffic to. If unspecified, default to the current URI path of the Route. Not applicable if the Plugin is mirroring gRPC traffic.                                                                                                                                                                                         |
| path\_concat\_mode | string | False    | replace | \["replace", "prefix"] | Concatenation mode when `path` is specified. When set to `replace`, the configured `path` would be directly used as the path of the host to forward the mirrored traffic to. When set to `prefix`, the path to forward to would be the configured `path`, appended by the requested URI path of the Route. Not applicable if the Plugin is mirroring gRPC traffic. |
| sample\_ratio      | number | False    | 1       | \[0.00001, 1]          | Ratio of the requests that will be mirrored. By default, all traffic are mirrored.                                                                                                                                                                                                                                                                                 |

**Sample configuration**

Minimal, mirror all traffic to a second host:

```json
{
  "proxy-mirror": {
    "host": "http://127.0.0.1:8081"
  }
}
```

Mirror only 10% of traffic to a specific path, prefixing the requested path:

```json
{
  "proxy-mirror": {
    "host": "http://127.0.0.1:8081",
    "path": "/mirror",
    "path_concat_mode": "prefix",
    "sample_ratio": 0.1
  }
}
```

</details>

### `request-id`

The `request-id` Plugin adds a unique ID to each request proxied through Helix, which can be used to track API requests. If a request carries an ID in the header and is not empty ("") corresponding to `header_name`, the Plugin will use the header value as the unique ID and will not overwrite with the automatically generated ID.

{% hint style="info" %}
**Priority** `12015` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

| Name                  | Type    | Required | Default                                                          | Valid values                           | Description                                                                                                                                                                                                                                                                                                                                                                   |
| --------------------- | ------- | -------- | ---------------------------------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| header\_name          | string  | False    | "X-Request-Id"                                                   |                                        | Name of the header that carries the request unique ID. Note that if a request carries an ID in the `header_name` header, the Plugin will use the header value as the unique ID and will not overwrite it with the generated ID.                                                                                                                                               |
| include\_in\_response | boolean | False    | true                                                             |                                        | If true, include the generated request ID in the response header, where the name of the header is the `header_name` value.                                                                                                                                                                                                                                                    |
| algorithm             | string  | False    | "uuid"                                                           | \["uuid","nanoid","range\_id","ksuid"] | Algorithm used for generating the unique ID. When set to `uuid` , the Plugin generates a universally unique identifier. When set to `nanoid`, the Plugin generates a compact, URL-safe ID. When set to `range_id`, the Plugin generates a sequential ID with specific parameters. When set to `ksuid`, the Plugin generates a sequential ID with timestamp and random number. |
| range\_id             | object  | False    |                                                                  |                                        | Configuration for generating a request ID using the `range_id` algorithm.                                                                                                                                                                                                                                                                                                     |
| range\_id.char\_set   | string  | False    | "abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789" | minimum length 6                       | Character set used for the `range_id` algorithm.                                                                                                                                                                                                                                                                                                                              |
| range\_id.length      | integer | False    | 16                                                               | >=6                                    | Length of the generated ID for the `range_id` algorithm.                                                                                                                                                                                                                                                                                                                      |

**Sample configuration**

Minimal, add a UUID request ID under the default header:

```json
{
  "request-id": {
    "header_name": "X-Request-Id"
  }
}
```

Use a compact `nanoid`, on a custom header, without echoing it in the response:

```json
{
  "request-id": {
    "header_name": "X-Trace-Id",
    "algorithm": "nanoid",
    "include_in_response": false
  }
}
```

Generate a `range_id` with a custom character set and length:

```json
{
  "request-id": {
    "algorithm": "range_id",
    "range_id": {
      "char_set": "abcdefghijklmnopqrstuvwxyz0123456789",
      "length": 20
    }
  }
}
```

</details>

### `request-validation`

The `request-validation` Plugin validates requests before forwarding them to Upstream services. This Plugin uses JSON Schema for validation and can validate headers and body of a request.

{% hint style="info" %}
**Priority** `2800` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

See [JSON schema specification](https://json-schema.org/specification) to learn more about the syntax.

| Name           | Type    | Required | Default | Valid values   | Description                                    |
| -------------- | ------- | -------- | ------- | -------------- | ---------------------------------------------- |
| header\_schema | object  | False    |         |                | Schema for the request header data.            |
| body\_schema   | object  | False    |         |                | Schema for the request body data.              |
| rejected\_code | integer | False    | 400     | \[200,...,599] | Status code to return when rejecting requests. |
| rejected\_msg  | string  | False    |         |                | Message to return when rejecting requests.     |

**Sample configuration**

Validate the request body against a JSON schema, requiring two fields:

```json
{
  "request-validation": {
    "body_schema": {
      "type": "object",
      "required": ["name", "email"],
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string", "format": "email" }
      }
    }
  }
}
```

Require a header and return a custom rejection code and message:

```json
{
  "request-validation": {
    "header_schema": {
      "type": "object",
      "required": ["Content-Type"],
      "properties": {
        "Content-Type": { "type": "string", "enum": ["application/json"] }
      }
    },
    "rejected_code": 422,
    "rejected_msg": "Invalid request headers"
  }
}
```

Validate both headers and body together:

```json
{
  "request-validation": {
    "header_schema": {
      "type": "object",
      "required": ["X-Api-Version"],
      "properties": {
        "X-Api-Version": { "type": "string" }
      }
    },
    "body_schema": {
      "type": "object",
      "required": ["id"],
      "properties": {
        "id": { "type": "integer" }
      }
    }
  }
}
```

</details>

### `traffic-split`

The `traffic-split` Plugin directs traffic to various Upstream services based on conditions and/or weights. It provides a dynamic and flexible approach to implement release strategies and manage traffic.

{% hint style="info" %}
**Priority** `966` · **Category** Traffic
{% endhint %}

<details>

<summary>Configuration and details</summary>

:::note

The traffic ratio between Upstream services may be less accurate since round robin algorithm is used to direct traffic (especially when the state is reset).

:::

| Name                                              | Type           | Required | Default    | Valid values                 | Description                                                                                                                                                                                                                                                                                        |
| ------------------------------------------------- | -------------- | -------- | ---------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| rules.match                                       | array\[object] | False    |            |                              | An array of one or more pairs of matching conditions and actions to be executed.                                                                                                                                                                                                                   |
| rules.match                                       | array\[object] | False    |            |                              | Rules to match for conditional traffic split.                                                                                                                                                                                                                                                      |
| rules.match.vars                                  | array\[array]  | False    |            |                              | An array of one or more matching conditions in the form of the gateway's expression syntax to conditionally execute the plugin.                                                                                                                                                                    |
| rules.weighted\_upstreams                         | array\[object] | False    |            |                              | List of Upstream configurations.                                                                                                                                                                                                                                                                   |
| rules.weighted\_upstreams.upstream\_id            | string/integer | False    |            |                              | ID of the configured Upstream object.                                                                                                                                                                                                                                                              |
| rules.weighted\_upstreams.weight                  | integer        | False    | weight = 1 |                              | Weight for each upstream.                                                                                                                                                                                                                                                                          |
| rules.weighted\_upstreams.upstream                | object         | False    |            |                              | Configuration of the upstream. Certain configuration options Upstream are not supported here. These fields are `service_name`, `discovery_type`, `checks`, `retries`, `retry_timeout`, `desc`, and `labels`. As a workaround, you can create an Upstream object and configure it in `upstream_id`. |
| rules.weighted\_upstreams.upstream.type           | array          | False    | roundrobin | \[roundrobin, chash]         | Algorithm for traffic splitting. `roundrobin` for weighted round robin and `chash` for consistent hashing.                                                                                                                                                                                         |
| rules.weighted\_upstreams.upstream.hash\_on       | array          | False    | vars       |                              | Used when `type` is `chash`. Support hashing on gateway variables, headers, cookie, Consumer, or a combination of gateway variables.                                                                                                                                                               |
| rules.weighted\_upstreams.upstream.key            | string         | False    |            |                              | Used when `type` is `chash`. When `hash_on` is set to `header` or `cookie`, `key` is required. When `hash_on` is set to `consumer`, `key` is not required as the Consumer name will be used as the key automatically.                                                                              |
| rules.weighted\_upstreams.upstream.nodes          | object         | False    |            |                              | Addresses of the Upstream nodes.                                                                                                                                                                                                                                                                   |
| rules.weighted\_upstreams.upstream.timeout        | object         | False    | 15         |                              | Timeout in seconds for connecting, sending and receiving messages.                                                                                                                                                                                                                                 |
| rules.weighted\_upstreams.upstream.pass\_host     | array          | False    | "pass"     | \["pass", "node", "rewrite"] | Mode deciding how the host name is passed. `pass` passes the client's host name to the upstream. `node` passes the host configured in the node of the upstream. `rewrite` passes the value configured in `upstream_host`.                                                                          |
| rules.weighted\_upstreams.upstream.name           | string         | False    |            |                              | Identifier for the Upstream for specifying service name, usage scenarios, and so on.                                                                                                                                                                                                               |
| rules.weighted\_upstreams.upstream.upstream\_host | string         | False    |            |                              | Used when `pass_host` is `rewrite`. Host name of the upstream.                                                                                                                                                                                                                                     |

**Sample configuration**

Weighted split between two existing Upstream objects (blue/green style rollout):

```json
{
  "traffic-split": {
    "rules": [
      {
        "weighted_upstreams": [
          { "upstream_id": "upstream-blue", "weight": 3 },
          { "upstream_id": "upstream-green", "weight": 1 }
        ]
      }
    ]
  }
}
```

Conditional split, route matching requests to a canary Upstream and the rest to the default:

```json
{
  "traffic-split": {
    "rules": [
      {
        "match": [
          { "vars": [["arg_canary", "==", "true"]] }
        ],
        "weighted_upstreams": [
          { "upstream_id": "upstream-canary", "weight": 1 }
        ]
      }
    ]
  }
}
```

Inline upstream nodes instead of referencing an Upstream object:

```json
{
  "traffic-split": {
    "rules": [
      {
        "weighted_upstreams": [
          {
            "upstream": {
              "type": "roundrobin",
              "pass_host": "node",
              "nodes": {
                "127.0.0.1:8081": 1
              }
            },
            "weight": 2
          },
          { "weight": 1 }
        ]
      }
    ]
  }
}
```

</details>

### `workflow`

The `workflow` Plugin supports the conditional execution of user-defined actions to client traffic based a given set of rules, defined using the gateway's expression syntax. This provides a granular approach to traffic management.

{% hint style="info" %}
**Priority** `1006` · **Category** Traffic · **Required** `rules`
{% endhint %}

<details>

<summary>Configuration and details</summary>

| Name          | Type           | Required | Default | Valid values | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------- | -------------- | -------- | ------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| rules         | array\[object] | True     |         |              | An array of one or more pairs of matching conditions and actions to be executed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| rules.case    | array\[array]  | False    |         |              | An array of one or more matching conditions in the form of the gateway's expression syntax. For example, `{"arg_name", "==", "json"}`.                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| rules.actions | array\[object] | True     |         |              | An array of actions to be executed when a condition is successfully matched. Currently, the array only supports one action, and it should be either `return`, or `limit-count` or `limit-conn`. When the action is configured to be `return`, you can configure an HTTP status code to return to the client when the condition is matched. When the action is configured to be `limit-count`, you can configure all options of the `limit-count` plugin, except for `group`. When the action is configured to be `limit-conn`, you can configure all options of the `limit-conn` plugin. |

**Sample configuration**

Return `403` to requests that match a condition:

```json
{
  "workflow": {
    "rules": [
      {
        "case": [["uri", "==", "/blocked"]],
        "actions": [
          ["return", { "code": 403 }]
        ]
      }
    ]
  }
}
```

Apply `limit-count` rate limiting only to requests that match a condition:

```json
{
  "workflow": {
    "rules": [
      {
        "case": [["arg_tier", "==", "free"]],
        "actions": [
          ["limit-count", { "count": 20, "time_window": 60, "rejected_code": 429 }]
        ]
      }
    ]
  }
}
```

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.digitalapi.ai/api-gateway/plugin-reference/plugins-traffic.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
