# How DNS load balancing works

> How a load balancer answers DNS queries from pools of origins, with health checks, location steering and failover.

Source: https://www.coritan.com/docs/websites/load-balancing/

In the dashboard:

- /dashboard/websites/…/load-balancing: https://www.coritan.com/dashboard/websites

A *load balancer* answers `A` and `AAAA` queries for one hostname in a zone, such as `api.example.com`, with the address of one of your servers. Coritan picks the server for each query from *origin pools*, skips servers that fail their health checks, and can send clients in different places to different pools. You manage both on a domain's **Load balancing** tab.

## Terms

*Origin*
: A server that can answer for the hostname, given by its public IPv4 or IPv6 address. An IPv4 origin answers `A` queries and an IPv6 origin answers `AAAA` queries.

*Origin pool*
: A named group of origins in one zone, such as the web servers in one data centre. The pool's algorithm decides which of its origins answers.

*Load balancer*
: A hostname in the zone and the pools that answer for it, in order, with the steering that reorders them.

*Steering*
: How the load balancer orders its pools for a query: as listed, at random, by where the client is, or by distance.

*Fallback pool*
: The pool that answers when every pool in the load balancer's order has no healthy origin.

## How a query is answered

1. Steering puts the load balancer's pools in order for this query.
2. Coritan goes down the order and skips disabled pools and pools with no healthy origin of the query's type.
3. The first pool left chooses one origin, and the answer carries that origin's address with the load balancer's TTL.
4. If no pool in the order can answer, the fallback pool tries.
5. If that fails too, Coritan answers with one of the enabled origins anyway, so the name keeps resolving while it has any.

Each answer holds one address. Visitors then connect straight to that origin: their traffic does not pass through Coritan's edge, its WAF or its certificates. For that, put a [web proxy](/docs/proxies/web-proxies/) in front of the hostname instead.

## Choosing an origin inside a pool

**Weighted round-robin**
: Picks a healthy origin at random, in proportion to its **Weight** from 1 to 100. An origin with weight 20 gets about twice the queries of one with weight 10.

**Failover (by priority)**
: Answers with the healthy origin that has the lowest **Priority** number. The others answer only while it is unhealthy.

The load balancer's **Session affinity** can change both. With **By client IP**, the same resolver gets the same origin while that origin stays healthy. Coritan sees the address of the visitor's DNS resolver, so every visitor behind one resolver gets the same origin. In a **Failover (by priority)** pool, **By client IP** spreads resolvers over all the healthy origins, whatever their priority.

## Health checks

An origin can have a **Health check** of **HTTP**, **HTTPS** or **TCP connect**. Coritan checks every enabled origin that has one once a minute, and a check fails when the origin does not answer within its **Timeout (s)**.

- An **HTTP** or **HTTPS** check asks for the check's **Path** at the origin's address and passes on a status from 200 to 399. The request names the IP address as its host, so the origin must answer a request that does not name your domain.
- An **HTTPS** check also verifies the origin's certificate against its IP address. A certificate that names only your domain fails it, so use **HTTP** or **TCP connect** for such an origin.
- A **TCP connect** check passes when the port accepts a connection.

An origin shows `healthy`, `unhealthy` or `unknown`. A new origin is `unknown` until its first check, and Coritan treats it as healthy until then. An origin with no check is always treated as healthy. **Run health checks** in a pool's menu checks its origins straight away.

## Steering

**Off**
: The load balancer tries its **Default pools** in the order you numbered them.

**Random**
: It puts the default pools in a random order for each query.

**Geographic**
: It matches the client's location against rules **By PoP**, then **By country**, then **By region**, and uses the pools of the first rule that matches. A client that no rule matches gets the default pools.

**Proximity**
: It ranks the pools by the distance from the client to each pool's **Primary location**. A pool without one comes last.

**Geographic** and **Proximity** need to know where the client is. **Locate the client by** sets how:

**Answering PoP**
: The client is where the Coritan nameserver that answered the query is: that PoP, its country and its region.

**Resolver IP**
: Coritan looks up the country of the resolver's IP address, and the region that country is in. **By PoP** rules do not match, because the resolver has no PoP. **Proximity** has no coordinates to measure from, so it keeps the pools in their listed order. When the address has no known country, Coritan uses the answering PoP instead.

## Load balancers and DNS records

A load balancer owns its hostname for `A`, `AAAA` and `CNAME` records. You cannot create one on a name that already has such records, and the zone refuses them at the name while the load balancer exists, even when it is off. While it is off, the name gets no `A` or `AAAA` answers. Other types at the name, such as `TXT` or `MX`, are unaffected. When you delete the load balancer, you can add records at the name again.

## Limits

| Limit | Value |
| --- | --- |
| Origin pools per zone | 50 |
| Origins per pool | 20 |
| Load balancers per zone | 50 |
| Pool entries per load balancer, across its default pools and every rule | 200 |
| TTL of a load balancer's answers | 5–3,600 seconds |

## Related

- [Create an origin pool](/docs/websites/load-balancing/create-an-origin-pool/)
- [Create a load balancer](/docs/websites/load-balancing/create-a-load-balancer/)
- [Load balancing reference](/docs/websites/load-balancing/reference/)
