# Firewall limits

A [firewall](/en/documentation/platform/firewall/) holds [rules](/en/documentation/platform/firewall/rules-engine/) and [function instances](/en/documentation/platform/firewall/functions-instances/). Each Product enabled on it adds objects of its own: [rule sets](/en/documentation/platform/firewall/waf/rules-set/) and [exceptions](/en/documentation/platform/firewall/waf/custom-allowed-rules/) for Web Application Firewall (WAF), [network lists](/en/documentation/platform/firewall/network-shield/network-lists/) for Network Shield, and a function instance for Bot Manager. This page states the bound Azion applies to each of those objects, the answer a call receives past it, and the usage each service plan includes.

The two kinds of value are different things. A default limit is checked on every call, and the call fails past it. An included amount is a billing quantity, and passing it changes what the account is charged rather than what the call returns.

---

## Rules and function instances

A firewall runs its rules in Rules Engine and runs a function through a function instance that a rule invokes. The bounds in this section apply to the rules and function instances of every firewall, whichever Products it has enabled.

### Default limits

Each row names what is bounded, the bound, and what a call past it receives.

| Scope                                                          | Limit                                         | Past the limit                                                                                                                                                                       |
| -------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Rule `description`                                             | Up to 1,000 characters                        | Azion Console shows `Description should not exceed 1000 characters`.                                                                                                                 |
| Criteria groups per rule                                       | 1 to 5                                        | Azion Console disables **Add Criteria** at 5 groups.                                                                                                                                 |
| Criteria per group                                             | 1 to 10                                       | Azion Console disables **And** and **Or** at 10 criteria in a group.                                                                                                                 |
| **Average Rate Limit** on a *Set Rate Limit* behavior          | At least 1                                    | Azion Console refuses a lower value.                                                                                                                                                 |
| **Maximum Burst Size** on a *Set Rate Limit* behavior          | At least 1, with the *Req/s* type only        | Azion Console refuses a lower value, and it does not send the field with the *Req/min* type.                                                                                         |
| Function instance `name`                                       | Up to 100 characters                          | `400` and `["Ensure this field has no more than 100 characters."]`                                                                                                                   |
| Arguments payload, the JSON object a function instance carries | 100,000 bytes                                 | `400` and `["Value size (in bytes) is too big. Maximum size allowed is 100000 bytes."]`                                                                                              |
| Azion API requests                                             | 200 per minute, on the `global-default` scope | A response carries `x-ratelimit-limit`, `x-ratelimit-remaining`, `x-ratelimit-reset`, and `x-ratelimit-scope`, which report the allowance left in the window and the time it resets. |

Three further bounds apply: a rule `name` takes 1 to 250 characters, a **Debug Rules** log carries 1.5 kB, and one firewall covers up to 200 domains.

The arguments payload bound is decimal: 100 KB means 100,000 bytes, not 100 KiB. A payload of 100,000 bytes is accepted, and a payload of 102,400 bytes, which is 100 KiB, is refused, so size the arguments object against the decimal figure. Azion can raise the arguments payload bound, and the other default limits of a function on a firewall, on request, based on your plan. To request an increase, contact the [technical support](/en/documentation/support/) team.

Size is the only property of the arguments object that the API checks. Every key an instance sends is stored and returned as sent, whatever its name. For example, a misspelled argument passes the call, and the function never reads it.

The number of function instances a firewall carries is not bounded. The count a firewall reaches is an operational choice rather than a value the platform checks.

A function that runs on a firewall shares the memory, environment variable, sub-request, and CPU time limits of every function. Those limits and the size of the function code belong to the function rather than to the firewall. For the values, refer to [Functions limits](/en/documentation/platform/functions/limits/).

The rate limit is the value that the response headers advertise. A response from the Azion API carries `x-ratelimit-limit: 200`, `x-ratelimit-scope: global-default`, and an `x-ratelimit-reset` timestamp about 60 seconds after the call. `x-ratelimit-remaining` stays one or two below the limit, and it does not count down during a burst of calls within a minute.

A call that the API accepts is not in effect at once. A new rule on a firewall already in traffic reaches it 6 min 29 s to 9 min 18 s after the call. A workload newly bound to a firewall can take several minutes to enforce its first rule, and no duration is guaranteed. While a change propagates, successive requests can receive the previous answer and the new one in turn, so send the request again until it answers as expected. For how a change reaches traffic, refer to [How Firewall works](/en/documentation/platform/firewall/how-it-works/).

### Included usage per plan

Azion offers three service plans: Hobby, Pro, and Enterprise. Firewall is billed on two metrics, Requests and Rules, and each plan includes an amount of each before a rate applies.

| Metric             | Hobby         | Pro           | Enterprise |
| ------------------ | ------------- | ------------- | ---------- |
| Firewall requests  | 10M per month | 20M per month | Custom     |
| Rules per firewall | 10            | 20            | Custom     |

Firewall meters every request that passes through a firewall, including the requests that a Network Shield rule evaluates. Enterprise carries a custom amount of Firewall requests and of rules per firewall. To request a custom amount, contact the [technical support](/en/documentation/support/) team.

For the rate that applies past an included amount, refer to [Pricing](/en/documentation/fundamentals/pricing/#firewall).

---

## WAF

WAF bounds the name a rule set takes, the conditions an exception carries, the size of the request body it inspects, and what one list request returns. Its default limits apply on every call, and its included amounts are billing quantities.

### Default limits

WAF applies each bound in this table on every service plan. The API answers a rejected call with a numeric `code`, a `title`, a `detail`, and a `source` pointer naming the field that failed. The Past the limit column carries the status, the code and title, and the text that arrives with them.

| Scope                                   | Limit                                         | Past the limit                                                                                                                                                                       |
| --------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Rule set `name`                         | Up to 250 characters                          | `400` `10046 Max Length`, `Ensure this field has no more than 250 characters.`                                                                                                       |
| Exception `name`                        | Up to 255 characters                          | `400` `10046 Max Length`, `Ensure this field has no more than 255 characters.`                                                                                                       |
| Exception condition `name` and `value`  | 1 to 255 characters                           | An empty value returns `400` `10018 Blank Field`, `This field may not be blank.`                                                                                                     |
| Conditions per exception                | At least 1; more than one is accepted         | An empty array returns `400` `10049 Min Length List Field`, `Ensure this field has at least 1 elements.`                                                                             |
| Records per list response (`page_size`) | 100 maximum, default 10                       | `400` `10097 Invalid Page Size`, `Page size must be between 0 and 100.`                                                                                                              |
| Azion API requests                      | 200 per minute, on the `global-default` scope | A response carries `x-ratelimit-limit`, `x-ratelimit-remaining`, `x-ratelimit-reset`, and `x-ratelimit-scope`, which report the allowance left in the window and the time it resets. |
| `thresholds` entries on a rule set      | 1 to 8, one per threat family                 | A repeated `threat` returns `500` `10067 Internal Server Error`, `A server error occurred.`                                                                                          |
| `rulesets`                              | `[1]`                                         | `400` `10039 Invalid Choice`, `"<value>" is not a valid choice.`                                                                                                                     |
| `engine_version`                        | `2021-Q3`                                     | `400` `10039 Invalid Choice`                                                                                                                                                         |
| `engine_settings.type`                  | `score`                                       | `400` `10039 Invalid Choice`                                                                                                                                                         |
| `operator` on an exception              | `contains` or `regex`, default `contains`     | `400` `10039 Invalid Choice`                                                                                                                                                         |
| `mode` on a `set_waf` behavior          | `logging` or `blocking`, and required         | An unlisted value, such as `learning`, returns `400` `10039 Invalid Choice`. A missing `mode` returns `400` `10059 Required Field`, `This field is required.`                        |
| Request body WAF inspects               | 131,072 bytes, which is 128 KiB               | `400` and Azion's default error page, not a `413`.                                                                                                                                   |
| WAF Tuning query window                 | 3 days                                        | No interface offers a longer range.                                                                                                                                                  |

WAF parses a `POST` body when its `Content-Type` is `application/x-www-form-urlencoded`, `multipart/form-data`, `application/json`, `application/vnd.api+json`, or `application/csp-report`. The body bound counts the body alone, without the request line and headers.

With `Content-Type: application/x-www-form-urlencoded` and a body that carries no attack pattern, a body of 131,072 bytes returns `200`, and a body of 131,073 bytes returns `400`. The event recorded for the refused request names rule `2` in the `BODY` zone, as `wafMatch` `0:2:BODY:-`, with `wafAttackFamily` `$OTHERS`. Rule `2` tests the size rather than adding to a score, so the bound holds at every sensitivity: a 170 KB body is refused at the default `medium` too. The event's `requestLength` also counts the request line and headers, so it reads higher than the body size: `131148` for a body of 131,073 bytes. The same body sent as `application/json` or `text/plain` is refused at both sizes, because rules `15` and `11` match the request before the size check. To test this boundary, send `application/x-www-form-urlencoded` or `multipart/form-data`.

The `500` that a repeated `threat` returns is a validation failure rather than a fault in the service. Send each of the eight threat families at most once in `thresholds`.

For the fields these bounds apply to, refer to [Rule sets](/en/documentation/platform/firewall/waf/rules-set/) and [Exceptions](/en/documentation/platform/firewall/waf/custom-allowed-rules/).

### Included usage per plan

WAF is billed on three metrics, Requests, Rule Sets, and Exceptions, and each plan includes an amount of each before a charge applies.

These amounts are billing quantities rather than bounds the platform applies to a call. A create request past an included amount of rule sets or exceptions is accepted, so the count an account reaches is a cost to watch rather than a rejection to handle.

| Metric                  | Hobby             | Pro               | Enterprise |
| ----------------------- | ----------------- | ----------------- | ---------- |
| Requests                | 100,000 per month | 200,000 per month | Custom     |
| Rule Sets               | 1                 | 2                 | Custom     |
| Exceptions per rule set | 10                | 20                | Custom     |

Enterprise carries a custom amount on all three metrics. To raise an included amount on any plan, contact the [technical support](/en/documentation/support/) team.

For the rate that applies past an included amount, refer to [Pricing](/en/documentation/fundamentals/pricing/#web-application-firewall).

---

## Network Shield

Network Shield lets a firewall rule match the client address of a request against a network list, through the `${network}` criterion. The Azion API bounds the size of a network list, its items, and its name, the records per list response, and the rate of calls.

Network Shield has no billing metric of its own. A rule that uses the `${network}` criterion is a firewall rule, so it counts toward the rules per firewall that each plan includes, and Firewall meters the requests it evaluates. For the amounts, refer to [Included usage per plan](/en/documentation/platform/firewall/limits/#included-usage-per-plan). For the rates, refer to [Pricing](/en/documentation/fundamentals/pricing/#network-shield). For which plans offer Network Shield, refer to [Azion pricing](https://www.azion.com/en/pricing/).

### Default limits

The Azion API applies each bound in this table by default. A call past a network list bound is refused with a `400` status and an `errors` array. Each entry carries a `code`, a `title`, a `detail`, and a `source` pointer naming the field that failed.

| Scope                                     | Limit                                         | Past the limit                                                                                                                                                                       |
| ----------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Items per network list                    | Up to 20,000 items                            | `400` `10065 List Field Max Length`, `Ensure this field has no more than 20000 elements.`                                                                                            |
| Items per network list, minimum           | At least 1 item                               | `400` `10049 Min Length List Field`, `Ensure this field has at least 1 elements.`                                                                                                    |
| Characters per item, annotations included | Up to 250 characters                          | `400` `10046 Max Length`, `Ensure this field has no more than 250 characters.`                                                                                                       |
| Characters per list `name`                | Up to 250 characters                          | `400` `10046 Max Length`, `Ensure this field has no more than 250 characters.`                                                                                                       |
| Records per list response (`page_size`)   | 100 maximum, default 10                       | `400` `10097 Invalid Page Size`, `Page size must be between 0 and 100.`                                                                                                              |
| Azion API requests                        | 200 per minute, on the `global-default` scope | A response carries `x-ratelimit-limit`, `x-ratelimit-remaining`, `x-ratelimit-reset`, and `x-ratelimit-scope`, which report the allowance left in the window and the time it resets. |

The item ceiling is exact, and it applies to the items of an IP/CIDR list and of an ASN list alike. A create call with 20,000 items returns `201`, and the same call with 20,001 items returns this body:

```json
{
  "errors": [
    {
      "code": "10065",
      "title": "List Field Max Length",
      "detail": "Ensure this field has no more than 20000 elements.",
      "status": "400",
      "source": { "pointer": "/data/items" }
    }
  ]
}
```

An item's 250 characters include its annotations: the `--LT` expiration date and the `#` comment that an `ip_cidr` item can carry. For example, an `ip_cidr` item of exactly 250 characters, an address followed by a `#` comment, is stored verbatim. For the item formats and annotations of each list type, refer to [Network Lists](/en/documentation/platform/firewall/network-shield/network-lists/).

When a call sets no `page_size`, the list endpoint returns 10 records per page. A `page_size` of `0` is refused with the same `10097` message, although the message names 0 as allowed.

The 20,000-item ceiling is a default limit, and Azion can raise it on request, based on the plan. To request an increase, contact the [technical support](/en/documentation/support/) team.

A change to a list's items is not in effect at once. It reaches traffic 46 s to about 100 s after the call, and until it settles, requests receive the previous answer and the new one in turn.

---

## Bot Manager

Bot Manager runs on a firewall as a function instance, which a rule with the *Run Function* behavior invokes. The function instance bounds of every firewall apply to it, and two more bounds apply to the surfaces around it: the report log and the GraphQL datasets.

### Default limits

A call past the function instance `name` or the arguments payload bound returns `400` with the message in the Past the limit column. The two surface bounds cap what the log field and a query return, and no call fails on them.

| Scope                                            | Limit                | Past the limit                                                                                                        |
| ------------------------------------------------ | -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Function instance `name`                         | Up to 100 characters | `400` and `["Ensure this field has no more than 100 characters."]`                                                    |
| Arguments payload                                | 100,000 bytes        | `400` and `["Value size (in bytes) is too big. Maximum size allowed is 100000 bytes."]`                               |
| Report log field `request_headers`               | 10,000 characters    | Each header name and value deducts from the amount, and the field takes no further header once the amount is reached. |
| GraphQL `limit` against the Bot Manager datasets | `10000` at most      | One query returns no more than 10,000 results.                                                                        |

The arguments payload bound is decimal, so a payload of 102,400 bytes, which is 100 KiB, is refused. For the arguments the payload holds and the default each one carries, refer to [Arguments](/en/documentation/platform/firewall/bot-manager/arguments/). For the report log, refer to [Logs](/en/documentation/platform/firewall/bot-manager/logs/). For the query, refer to [Query Bot Manager data with GraphQL](/en/documentation/guides/platform/observability/query-bot-manager-data-with-graphql/).

### Included usage per plan

Bot Manager is billed on two metrics, Requests and Profiles. These amounts are billing quantities rather than bounds applied on a call. Passing one of them fails no request, so no error string belongs to this table.

| Metric           | Hobby             | Pro               | Enterprise |
| ---------------- | ----------------- | ----------------- | ---------- |
| Bot Manager Lite | Included          | Included          | Custom     |
| Bot Manager      | Not listed        | Not listed        | Custom     |
| Requests         | Billed per 10,000 | Billed per 10,000 | Custom     |
| Profiles         | 1                 | 1                 | Custom     |

No included volume of requests is published for Bot Manager on any plan. The table carries the increment that requests are billed in, which is 10,000. Each plan carries one profile, and a profile past the first is billed.

[Bot Manager Lite](/en/documentation/platform/firewall/bot-manager/bot-manager-lite/) is included on all three plans. The full edition is listed on Enterprise alone, where each amount is custom. For the rate that applies to requests and to profiles, refer to [Pricing](/en/documentation/fundamentals/pricing/#bot-manager).

---

## Related resources

- [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine.md#rule-fields): The rule fields that the name, description, and criteria bounds on this page apply to.
- [Functions limits](/en/documentation/platform/functions/limits.md): The memory, CPU time, sub-request, environment variable, and code size limits of every function.
- [How Firewall works](/en/documentation/platform/firewall/how-it-works.md): How a request passes through a firewall's rules, and how long a change takes to reach traffic.
- [Troubleshoot Firewall](/en/documentation/platform/firewall/troubleshooting.md): What to do about a call or a request that one of these bounds refused.
