Load balancers
A load balancer is a public address in front of your instances and apps. Each listener opens one public port and forwards it to a target group: the instances, apps or addresses behind it, with a balancing rule and a health check. Load balancers are in the dashboard under Load balancers.
Tiers
The tier sets the kind of address, how many listeners the load balancer includes and how much traffic it may process each month. You pick it when you create the load balancer, and it stays for the load balancer's life.
| Tier | Address | Listeners | Traffic per month | Today |
|---|---|---|---|---|
| Free | Your workspace's shared IP, ports 40000–49999 | 5 | 1 TB | Available |
| Standard | A dedicated IPv4 address, any port | 20 | 20 TB | Not offered yet |
| Premium | A dedicated IPv4 address, any port | 50 | 50 TB | Not offered yet |
The create form shows Standard and Premium marked Not offered yet, and they cannot be created, so every load balancer is on the Free tier for now.
A Free load balancer that processes its 1 TB within a calendar month (UTC) is throttled until the month rolls over: each of its listeners is limited to about 1 Mbit/s. The workspace's owners get an email when it reaches 80% of the allowance and again at 100%, and its Overview shows Traffic is throttled while it lasts.
How many you can have
| Workspace owner's plan | Load balancers per workspace |
|---|---|
| Free | 1 |
| Pro | 5 |
| Scale | 20 |
Each Service of type LoadBalancer in a Kubernetes cluster uses one of them too. At the limit, delete a load balancer you no longer use, or contact support to raise it.
Where clients connect
Every load balancer gets a DNS name of its own under lb.sahabti.app, made from its name and a short random suffix, such as web-k3x9mq.lb.sahabti.app. It stays the same for the load balancer's life, even when you rename it. Its Overview shows where clients connect under Endpoint, and the Listeners tab shows each listener's Public endpoint, ready to copy.
On the shared IP, the platform gives each listener a public port of its own from 40000–49999 when you add it. Clients connect to the DNS name with that port, for example web-k3x9mq.lb.sahabti.app:40006. Nothing answers on the DNS name without a port.
To use your own domain, point it at the DNS name with a CNAME record. Clients still connect with the listener's port.
HTTPS without a port
The shared IP has no port 443 to give a load balancer, so https:// with no port in the address cannot reach one. To serve a website or an API over HTTPS on the standard port, deploy it as a web app, which is served over HTTPS at a hostname of its own, or run it in a Kubernetes cluster behind its managed gateway. Both take care of the certificates for you.
Create a load balancer
Choose Load balancers → New load balancer. Four steps take you from an empty load balancer to a working port, and each one is saved as you finish it:
- Load balancer: its Name (up to 63 characters on one line, unique in the workspace), the Network its targets live in, the Tier and the Protection profile. Every target must be on that network, and the network must be ready.
- Target group: where traffic goes, with its protocol, port, balancing and health check. See Target groups.
- Targets: the instances, apps or addresses in the group. See Targets.
- Listener: the public port clients connect to. See Listeners.
Skip for now on the targets step and Finish without a listener on the last one leave those for later, and Finish later takes you to the load balancer as it is. Its Overview then says what is still missing: a target group, or a listener. A new load balancer shows Pending, then Provisioning, then Ready.
Rename on the load balancer's page changes its label only: the tier and the DNS name stay as they are.
Listeners
A listener is one public port on the load balancer's address, forwarded to a target group. Anything no listener opens is closed. Add one from the Listeners tab with Add listener:
| Protocol | For | Forwards to |
|---|---|---|
| TCP | Plain TCP: databases, SSH, game servers | A TCP target group |
| UDP | Plain UDP: DNS, game servers, VPNs | A UDP target group |
| TCP + UDP | Both protocols on the same port | A TCP target group |
| TLS (terminated) | TLS ends at the load balancer with your certificates, and the target sees plain TCP | A TCP target group |
| TLS passthrough | TLS reaches the target still encrypted, and the target ends it | A TCP target group |
- Public port: on the shared IP it is allocated from 40000–49999 when the listener is created.
- Allowed sources: up to 20 IPv4 addresses or CIDR ranges, one per line. Only they can connect, they skip the protection limits, and an empty list means anyone. A bare address counts as a
/32, a range is saved by its first address, so198.51.100.9/24becomes198.51.100.0/24, and0.0.0.0/0anywhere in the list means anyone. - Idle timeout: how long a connection may stay idle before it is closed, from 10 to 3600 seconds, 60 by default. It applies on the proxied path, below.
- Protection overrides: limits of this listener's own. See Per-listener overrides.
Protocol and port cannot change once the listener exists: remove it and add it again. Edit listener changes everything else. Removing a listener cuts its open connections within a few seconds, and its shared port returns to the pool. The tab shows how many of your tier's listeners are in use.
Accelerated and proxied
Each listener shows the path its traffic takes, which the platform picks from the listener and its target group:
- Accelerated: forwarded without a proxy, the fastest path. UDP traffic always takes it, and so does a TCP listener with one enabled target, no health check and no PROXY protocol.
- Proxied: every other listener. Balancing, health checks, stickiness and TLS happen here.
TLS and certificates
A TLS (terminated) listener ends TLS at the load balancer and passes plain TCP to its targets. It needs at least one certificate from your workspace's Certificates page, and takes up to 20:
- Clients are matched to a certificate by the server name they send. The Default certificate serves clients that send none.
- TLS policy: Modern, the default, accepts TLS 1.3, and TLS 1.2 with AEAD ciphers. Compatible accepts TLS 1.2 and later, with older ciphers for older clients.
- The listener offers no ALPN, so browsers speak HTTP/1.1 through it, and your targets serve plain TCP or HTTP.
To replace a certificate, import the new one, attach it with Edit listener, then delete the old one: a certificate attached to a listener cannot be deleted.
A TLS passthrough listener needs no certificate. The connection reaches your targets still encrypted, and they hold the certificate.
Target groups
A target group is where listeners forward to: its targets, and how traffic is spread over them and checked. Several listeners can share one group. Add one from the Target groups tab with Add target group:
| Setting | Values |
|---|---|
| Protocol | TCP or UDP. It is fixed once the group exists, because listeners are matched against it |
| Port | The port targets listen on, unless a target sets its own |
| Balancing | Round robin, Least connections or Source hash |
| Stickiness | None, or By source address: a client keeps reaching the same target until 30 minutes pass without a connection from it |
| Client IP | What the targets see as the source of a connection. See The client's address |
| Health check | No check, TCP connect or HTTP GET. See Health checks |
Balancing and stickiness apply on the proxied path. UDP traffic is spread by the client's address instead, so each client stays on one healthy target.
A load balancer holds up to 50 target groups. A group a listener forwards to cannot be removed: point the listener at another group, or remove it, first.
Health checks
A target that fails its group's check is taken out of rotation until it passes again.
- TCP connect: the check opens a connection to the target.
- HTTP GET: the check requests the Path you set, which starts with
/, and passes on any status from 200 to 399. - No check: every enabled target gets traffic, and the load balancer never learns that one is down. Use it for a single target, or for a service with nothing to probe.
The check uses the group's port unless you set a Check port. The Interval is 2 to 300 seconds, 10 by default, and the Timeout, how long a check waits, is 1 to 60 seconds, 5 by default, and shorter than the interval. A target turns healthy after Passes before healthy checks in a row and unhealthy after Failures before unhealthy, each 1 to 10 and 3 by default. A UDP group can only use TCP connect, so give it a check port where the target accepts TCP.
Health
The load balancer's Health sums up its targets: Healthy when every target behind its listeners can serve, Degraded when some cannot but traffic still flows, Failed when nothing it exposes can be served, and Unknown while a new load balancer without listeners is still being set up. A target in a group without a health check counts as able to serve. In its group, each target shows Healthy, Unhealthy or Unknown.
Under an unhealthy target, the Target groups tab says why:
| Reason | What to check |
|---|---|
| Connection refused | Nothing listens on the target's port: check the port and that the service runs. |
| Cannot be reached | The target's address is not reachable on the network. |
| Could not connect | The check could not open a connection to the target: check its address and port. |
| Did not accept the connection in time | A firewall drops the connection, or the target is overloaded. |
| TLS handshake failed | The target and the check disagree about TLS. |
| Did not answer the check in time | The target accepts connections but answers too slowly. |
| Answer not valid | The target answered the HTTP check with something other than HTTP. |
| HTTP status | The HTTP check got an error status, such as 404 for a wrong path or 503 while the app starts. |
| Check could not run | The check itself failed on the platform's side. If it persists, contact support. |
Targets
Add targets to a group with Add target. A target is one of:
- Instances: a managed service or a virtual machine of this workspace on the load balancer's network. A managed service's port is filled in for you; for a virtual machine, enter the port your service listens on.
- Apps: a web app on that network, at the port it publishes.
- Custom: any IPv4 address inside the network's range, with a port.
A target uses the group's port unless you give it one of its own. Its Weight, 0 to 256 and 1 by default, sets its share of new connections on the proxied path, and 0 sends it none on either path, shown as Draining. Switch its Enabled column off to take it out of rotation without removing it. To point a target somewhere else, remove it and add another.
A group holds up to 20 targets, and each backend can be in it only once. Instances and apps are followed automatically: if one gets a new private address, the load balancer follows it.
The client's address
By default your targets see connections coming from the load balancer, not from the client. A target group's Client IP setting changes that:
| Client IP | What targets see |
|---|---|
| Hidden (default) | The load balancer's address. Nothing about the targets changes |
| Preserve client IP | The real client address. While an instance is a target of the group, its default route goes through the load balancer, so that replies return the same way, and it is put back when the instance leaves the group or the load balancer is deleted. Only instance targets are rerouted, so use it with instances |
| PROXY protocol v2 | The client's address and port in a PROXY protocol v2 header at the start of each connection. TCP groups only, and the target software must support it |
Turn PROXY protocol on in the server that receives the connections before you choose it: a server that does not expect the header treats it as a broken request.
Protection
Every load balancer drops floods above a set rate on its listener ports, and bans a source that opens connections too fast, holds too many at once, or keeps closing them within 4 seconds of opening them, as password guessing does. You pick the profile when you create the load balancer, and change it on the Security tab with Apply profile:
| Standard | Strict | |
|---|---|---|
| SYN packets per second, per listener | 5,000 | 2,000 |
| New connections per second, per source | 50 | 20 |
| Concurrent connections, per source | 200 | 50 |
| Connections closed within 4 seconds, per minute, per source | 100 | 30 |
| Ban for a source that trips a limit | 10 minutes | 1 hour |
| UDP packets per second, per listener | 20,000 | 5,000 |
Strict suits exposed databases and admin ports. A change is live within a few seconds. A listener's Allowed sources skip these limits and are never banned on it, but a denied source stays denied and the Free tier's throttle still applies.
Per-listener overrides
Under Protection overrides, a listener can set limits of its own. A field left empty follows the profile:
| Override | Range |
|---|---|
| New connections per second, per source | 1 to 100,000 |
| Concurrent connections, per source | 1 to 100,000 |
| Ban duration | 60 seconds to 7 days |
| UDP packets per second | 100 to 1,000,000 |
Ban sources for many short connections is on by default. Turn it off for a port that legitimately sees many, such as clients behind one office address or monitoring probes. A Kubernetes Service sets it with its lb.sahabti.com/short-session-bans annotation: see Configure a LoadBalancer Service.
Blocked and denied sources
The Security tab lists two kinds of shut-out source:
- Blocked sources were banned by the load balancer for tripping a limit. A ban expires on its own; Unban lifts it early, within a few seconds, if it was a false alarm. A source that keeps offending is banned again.
- Denied sources are addresses you never want to hear from. Add an IPv4 address or CIDR range with an optional reason, up to 200 per load balancer, and it is dropped before any listener for as long as it is listed. Remove lets it back in.
Bans and denied sources apply to listener ports only, never to your instances' own ports on the same address. On the shared IP, they cover the listener ports of all your load balancers there.
The same tab lists each listener's Allowed sources, with Edit sources to change them.
Monitoring
The Monitoring tab charts each listener's bytes in and out, new and open connections, and healthy targets, sampled every minute, over the last hour, 24 hours, 7 days or 30 days. Totals sums bytes and connections per listener over the same window. Samples appear a few minutes after the first listener goes live.
The page's header shows the load balancer's Status, its Health and its Changes: Applying… while a change is being put in place, then Live. When a change cannot be applied, the Overview says The last change could not be applied: fix the listener or target it names, and the next change applies everything again.
Usage
The Overview shows Traffic this month: the bytes the load balancer processed this calendar month against its tier's allowance.
Your workspace's Usage page has a Metered card that lists, for each month, every load balancer's Load balancer hours and Bytes processed, estimated from list prices. A Free load balancer costs nothing: its hours are priced at zero and its bytes are not billed. A deleted load balancer's lines stay, marked Deleted. The same card lists your Kubernetes clusters' usage: see Kubernetes pricing and usage.
Delete a load balancer
On the load balancer's page, choose Delete and type confirm to confirm. It stops answering within a few seconds. Its listeners, target groups and targets are removed, its shared ports return to the pool, its DNS name is withdrawn, and any instance rerouted for Preserve client IP gets its usual route back. This cannot be undone.
Who can do what
| Owner | Admin | Developer | Viewer | |
|---|---|---|---|---|
| See load balancers, their monitoring and usage | ✓ | ✓ | ✓ | ✓ |
| Create, change and delete load balancers | ✓ | ✓ | — | — |
An API token carries the loadbalancer scope with create, read, update and delete; update covers listeners, target groups, targets and protection.
Load balancers of a Kubernetes cluster
A Service of type LoadBalancer in a cluster gets one of your workspace's load balancers, on the Free tier. It is listed on the Load balancers page, marked Kubernetes, and read-only: its settings come from the Service, as Configure a LoadBalancer Service explains, and deleting the Service releases it.
From the API and MCP
Everything on this page is in the API under /v1/load-balancers, and in MCP as tools such as create_load_balancer, add_lb_target_group, add_lb_target, add_lb_listener, set_lb_protection, deny_lb_source and get_lb_metrics. A write is answered at once and applied within seconds: read the load balancer back until pendingChanges is false to know it is live.