---
name: azion-balance-traffic-across-multiple-origins
description: >-
  Spread the requests of an application across several origin addresses with a Load Balancer connector and a Rules Engine rule that sets it.
---

# Balance traffic across multiple origins

You can spread the requests of an [application](/en/documentation/platform/applications/) across several origin servers by enabling [Load Balancer](/en/documentation/platform/connectors/#load-balancer) on a [connector](/en/documentation/platform/connectors/). A [Rules Engine](/en/documentation/platform/applications/rules-engine/) rule then sends the requests to that connector, and Load Balancer distributes them among its addresses with a balancing algorithm. To connect an application to a single origin, refer to [Connect an application to an origin](/en/documentation/guides/application-development/getting-started/work-with-origins/).

An account that [has not migrated to API v4](/en/documentation/guides/application-security/access-and-compliance/verify-account-migration/) configures load balancing in the legacy Origins of the application. For more information, refer to [Origins](/en/documentation/platform/connectors/origins/#load-balancer).

> **Caution**
>
> With Load Balancer enabled, data transfer can generate usage-related costs. For more information, refer to [Pricing](/en/documentation/fundamentals/pricing/).

> **Tip**
>
> This page carries separate instructions for API v4 and API v3. To find out which apply to your account, refer to [Verify your account migration](/en/documentation/guides/application-security/access-and-compliance/verify-account-migration/).

---

## Prerequisites

### Console

- An application served by a [workload](/en/documentation/platform/workloads/). To create both, refer to [Applications quickstart](/en/documentation/platform/applications/quickstart/).
- Two or more origin servers that hold the same content and are set up the same way for the application.
- Access to Azion Console. To sign in, refer to [Access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).

### API

- An application served by a [workload](/en/documentation/platform/workloads/). To create both, refer to [Applications quickstart](/en/documentation/platform/applications/quickstart/).
- Two or more origin servers that hold the same content and are set up the same way for the application.
- A personal token, sent in the `Authorization` header as `Token [TOKEN VALUE]`. To create one, refer to [Manage a personal token](/en/documentation/guides/platform/account-and-billing/personal-tokens/).
- `curl`, or another HTTP client.
- The ID of the application. Azion Console shows it in the address of the application's page, after `/applications/edit/`.

---

## Plan the addresses

The example on this page balances three origin servers. Each one is hosted with a different storage provider or cloud service, because server outages rarely occur at the same time. All three hold the same content and are set up the same way for the application. Two of them share the traffic, and the third stands by for maintenance and traffic surges.

| Address       | Server    | Load capacity                              | Weight                                         | Server role | Active                                     |
| ------------- | --------- | ------------------------------------------ | ---------------------------------------------- | ----------- | ------------------------------------------ |
| `example.com` | Primary   | High                                       | `3`                                            | `primary`   | Always                                     |
| `example.net` | Secondary | Medium, enough for large surges of traffic | `2`                                            | `primary`   | Always                                     |
| `example.org` | Backup    | Low                                        | `1`, the default when the weight is left blank | `backup`    | Only during maintenance or a traffic surge |

The weight follows the load capacity of each server. Both `example.com` and `example.net` are primary, and the higher weight makes `example.com` the preferred address for connections. `example.org` stays inactive until maintenance or a surge needs it. For how the weight, the server role, and the active state distribute requests, refer to [Load Balancer](/en/documentation/platform/connectors/load-balancer/balancing-methods/#weight).

---

## Create a connector with Load Balancer

Load Balancer belongs to the connector, under `attributes.modules` in the API. A connector created without Load Balancer keeps it disabled until you enable Load Balancer on the connector. This is the `attributes.modules` object of an HTTP connector the API created with no load balancing:

```json
{
  "load_balancer": {
    "enabled": false,
    "config": null
  },
  "origin_shield": {
    "enabled": false,
    "config": null
  }
}
```

To balance the three addresses of the example with the [Round-Robin algorithm](/en/documentation/platform/connectors/load-balancer/balancing-methods/#balancing-method), the connector carries these values. Each key is under `attributes`:

| Key                                               | Value in the example                                              |
| ------------------------------------------------- | ----------------------------------------------------------------- |
| `type`                                            | `http`                                                            |
| `modules.load_balancer.enabled`                   | `true`                                                            |
| `modules.load_balancer.config.method`             | `round_robin`                                                     |
| `modules.load_balancer.config.max_retries`        | `0`                                                               |
| `modules.load_balancer.config.connection_timeout` | `60`                                                              |
| `modules.load_balancer.config.read_write_timeout` | `120`                                                             |
| `addresses[].address`                             | `example.com`, `example.net`, and `example.org`                   |
| `addresses[].modules.load_balancer.weight`        | `3`, `2`, and `1`                                                 |
| `addresses[].modules.load_balancer.server_role`   | `primary`, `primary`, and `backup`                                |
| `addresses[].active`                              | `true`, `true`, and `false`                                       |
| `connection_options.transport_policy`             | `preserve`                                                        |
| `connection_options.host`                         | `${host}`, which forwards the `Host` header of the user's request |

In Azion Console, you set up connectors in the Connectors menu, not in a tab of the application. For each field, refer to [Load Balancer](/en/documentation/platform/connectors/#load-balancer) and [Connector settings](/en/documentation/platform/connectors/settings/#addresses).

### Console

To create the connector in Azion Console:

1. **Open the Connectors page**

   Access [Azion Console](https://console.azion.com/) > **Connectors**.

2. **Start a new connector**

3. **Name the connector**

   In the **General** section, enter `balanced-origins` in **Name**.

4. **Select the HTTP type**

   In the **Connector Type** section, select the HTTP type.

5. **Turn on Load Balancer**

   In the **Modules** section, turn on **Load Balancer**. The connector then accepts more than one address.

6. **Select the method**

   In the **Load Balancer Configuration** section, select *Round Robin* in **Method**.

7. **Turn off retries**

   Enter `0` in **Max Retries**, the value for no retries.

8. **Set the timeouts**

   Enter `60` in **Connection Timeout** and `120` in **Read/Write Timeout**.

9. **Set the first primary address**

   In the **Address Management** section, enter `example.com` in **Address** and `3` in **Weight**. Select *Primary* in **Server Role**, and keep **Active** turned on.

10. **Add a second address**

11. **Set the second primary address**

    Enter `example.net` in **Address** and `2` in **Weight**. Select *Primary* in **Server Role**, and keep **Active** turned on.

12. **Add a third address**

13. **Set the backup address**

    Enter `example.org` in **Address** and `1` in **Weight**. Select *Backup* in **Server Role**, and turn off **Active**.

14. **Keep the protocol of the user's request**

    In **Transport Protocol Policy**, select the option that preserves the protocol of the user's request.

15. **Forward the Host header of the user's request**

    Enter `${host}` as the host the connector sends in the `Host` header to the origin.

16. **Select Create**

Azion Console shows `Connector successfully created`.

### API

To create the connector with the API, send the values of the table in a `POST` request to `/v4/workspace/connectors`. Copy the ID of the connector, which the API returns in `data.id`. The rule that sends requests to the connector names it by this ID.

---

## Send requests to the connector

A connector receives no request until a rule sets it. The rule in this section runs in the Request Phase of the application. Its criterion matches every path, with the `${uri}` variable, the `starts_with` operator, and `/` as the argument, so the connector serves the whole application. Its behavior sets the connector.

The `${uri}` variable works on every application. A criterion on `${request_uri}` needs [Application Accelerator](/en/documentation/platform/applications/application-accelerator/quickstart/) on the application. For every variable and operator, refer to [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine/#criteria).

### Console

To create the rule in Azion Console:

1. **Open the application**

   Access [Azion Console](https://console.azion.com/) > **Applications**, then select your application.

2. **Select the Rules Engine tab**

3. **Start a rule**

   Select **+ Rule**.

4. **Name the rule**

   In the **General** section, enter a **Name**, such as `balance-origins`.

5. **Select the phase**

   In the **Phase** section, select *Request Phase*. A rule keeps the phase it is created in.

6. **Set the criterion**

   In the **Criteria** section, set the variable to `${uri}`, the operator to `starts_with`, and the argument to `/`.

7. **Set the connector**

   In the **Behaviors** section, select *Set Connector*, then select the connector with Load Balancer in **Connector**.

8. **Save the rule**

   Select **Save**.

The rule appears in the **Rules Engine** tab of the application, under **Request**.

### API

To create the rule with the API, send a `POST` request to the `request_rules` endpoint of the application. Replace `<application-id>` with the ID of your application, and `<connector-id>` with the ID of the connector:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/applications/<application-id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "balance-origins",
  "active": true,
  "criteria": [
    [
      {
        "variable": "${uri}",
        "conditional": "if",
        "operator": "starts_with",
        "argument": "/"
      }
    ]
  ],
  "behaviors": [
    {
      "type": "set_connector",
      "attributes": {
        "value": <connector-id>
      }
    }
  ]
}'
```

The API answers `202` and returns the rule:

```json
{
  "state": "pending",
  "data": {
    "id": <rule-id>,
    "name": "balance-origins",
    "active": true,
    "criteria": [
      [
        {
          "conditional": "if",
          "variable": "${uri}",
          "operator": "starts_with",
          "argument": "/"
        }
      ]
    ],
    "behaviors": [
      {
        "type": "set_connector",
        "attributes": {
          "value": <connector-id>
        }
      }
    ],
    "description": "",
    "order": 0,
    "last_editor": "user@example.com",
    "last_modified": "2026-01-01T12:00:26.750242Z",
    "created_at": "2026-01-01T12:00:26.750262Z"
  }
}
```

The rule is the first of the application's Request Phase, at `order` `0`.

For the behavior and its attributes, refer to [Set Connector](/en/documentation/platform/applications/rules-engine/#set-connector).

---

## Confirm that the application answers

The rule takes a few minutes to propagate. Until then, the application answers as it did before the rule existed.

To confirm the route, send a request to the domain of your workload, with that domain in place of `<your-workload-domain>`:

```bash
curl -i https://<your-workload-domain>/
```

The response comes from one of the active addresses of the connector. A workload's domain ends in `.map.azionedge.net`, and the API returns it in `workload_domain` when it creates the workload. If the response does not come from your origin servers yet, send the request again until it does. If it never does, refer to [Troubleshoot Applications](/en/documentation/platform/applications/troubleshooting/).

---

## Balance the addresses on a v3 application

An account that runs on API v3 has no connectors: load balancing belongs to an origin of the application, of the **Load Balancer** type. To find out which model your account runs on, refer to [Verify your account migration](/en/documentation/guides/application-security/access-and-compliance/verify-account-migration/).

**Console**

Load Balancer is a setting on the application, and the addresses sit on one origin. To set both in Azion Console:

1. **Open the application**

   Access [Azion Console](https://console.azion.com/) > **Applications** > **your application**.

2. **Turn on Load Balancer**

   In the **Main Settings** tab, under **Modules**, turn on **Load Balancer**.

3. **Save the application**

4. **Open the origin**

   In the **Origins** tab, select **Default Origin** to balance the addresses the application already uses, or **+ Origin** to add a separate one. Editing the default origin replaces the address the application was created with.

5. **Name the origin and choose its type**

   Enter a name and set **Type** to **Load Balancer**.

6. **Choose the balancing method**

   In **Method**, select the method you want. For example: **Round-Robin**.

7. **Add the first address**

   In the first **Address** field, enter the primary server. In **Weight**, enter its share of the requests, such as `3` for a server with more capacity. In **Server Role**, keep **Primary**, and keep the address **Active**.

8. **Add the other addresses**

   Select **+ Add Origin** for each further address. A **Weight** left blank takes `1`. An address with **Server Role** set to **Backup** receives requests only when the primary addresses fail, and an address with **Active** off receives none.

9. **Save the origin**

   Select **Save**.

**API v3**

To balance the addresses with API v3, first read the `origin_key` of the origin you want to change. The request carries the header `Accept: application/json; version=3`:

```bash
curl --request GET \
  --url https://api.azionapi.net/edge_applications/<application-id> \
  --header 'Accept: application/json; version=3' \
  --header 'Authorization: Token [TOKEN VALUE]'
```

The response carries `origin_key`, a UUID, beside `origin_type` and the name of the origin:

```json
{
  "results": {
    "origin_id": 123456,
    "origin_key": "bdcd7003-ba53-4ed8-8ca0-05b1357cdafd",
    "name": "Default Origin",
    "origin_type": "single_origin"
  }
}
```

Then send a `PATCH` to that origin with the full list of addresses:

```bash
curl --request PATCH \
  --url https://api.azionapi.net/edge_applications/<application-id>/origins/<origin-key> \
  --header 'Accept: application/json; version=3' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --data '{
  "name": "Default Origin (RR3)",
  "origin_type": "load_balancer",
  "method": "round_robin",
  "host_header": "${host}",
  "addresses": [
    { "address": "example.com", "weight": 3, "server_role": "primary", "is_active": true },
    { "address": "example.net", "weight": 2, "server_role": "primary", "is_active": true },
    { "address": "example.org", "weight": 1, "server_role": "backup", "is_active": false }
  ]
}'
```

| Key                       | What it carries                                                                    |
| ------------------------- | ---------------------------------------------------------------------------------- |
| `origin_type`             | `load_balancer` turns the origin into a balanced one. Load Balancer has to be on   |
| `method`                  | The balancing method, such as `round_robin`                                        |
| `addresses[].weight`      | The share of requests the address takes. Omitted, it is `1`                        |
| `addresses[].server_role` | `primary`, or `backup` for an address that answers only when the primary ones fail |
| `addresses[].is_active`   | `false` keeps the address in the list and out of rotation                          |

The response returns the origin as Azion stored it, with the addresses in the order you sent them:

```json
{
  "results": {
    "origin_id": 123456,
    "origin_key": "bdcd7003-ba53-4ed8-8ca0-05b1357cdafd",
    "name": "Default Origin (RR3)",
    "origin_type": "load_balancer",
    "method": "round_robin",
    "addresses": [
      { "address": "example.com", "weight": 3, "server_role": "primary", "is_active": true },
      { "address": "example.net", "weight": 2, "server_role": "primary", "is_active": true },
      { "address": "example.org", "weight": 1, "server_role": "backup", "is_active": false }
    ]
  }
}
```

The rule that sends requests to the origin is the **Set Origin** behavior of the application's **Rules Engine**, in place of **Set Connector**. For every field of the origin, refer to [Origins](/en/documentation/platform/connectors/origins/).

---

## Next steps

- [Load Balancer](/en/documentation/platform/connectors.md#load-balancer): The balancing methods, and how weight, server role, and the active state distribute requests.
- [Connectors](/en/documentation/platform/connectors.md): Every connection option of an HTTP connector, and the other connector types.
- [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine.md): Send part of the application to the connector with a narrower criterion.
- [Connect an application to an origin](/en/documentation/guides/application-development/getting-started/work-with-origins.md): Create a connector to a single HTTP origin, and the rule that sets it.
