Self-HostedHigh availabilityNetworking

Load balancing self-hosted servers

Four ways to put a stable address in front of multiple self-hosted instances - DNS round robin, weighted DNS, and load balancers with or without per-instance public IPs.
Updated August 27, 2026

Running two or more self-hosted instances keeps your FTP service available when a server fails. All instances share the same cloud-managed configuration, so the question is only how client connections reach them. Deciding which approach fits your protocols and priorities is covered in Clustering recommendations - this page is the how-to for configuring each one. There are four common approaches:

  1. DNS round robin
  2. DNS weighted records
  3. A load balancer, with a public IP per instance
  4. A load balancer, with no public IP per instance

FTP's passive mode is what makes this interesting: after connecting, the server tells the client an IP address to open data connections to (the -publicip flag), and that address must route back to the same instance.

DNS round robin

The simplest approach: multiple A records on one name.

Server1 started with:  -publicip 1.1.1.1
Server2 started with:  -publicip 2.2.2.2

ftp.mycompany.com.  A  1.1.1.1
ftp.mycompany.com.  A  2.2.2.2

Clients pick one of the records; each instance hands out its own public IP for passive connections, so data connections come straight back to it.

Add a health check that removes a dead instance's record from DNS, or a portion of connection attempts will fail until it returns.

DNS weighted records

Same layout as round robin, but the DNS service (e.g. Amazon Route 53) serves one IP per query, weighted across the instances, instead of the whole list. Health checks integrate cleanly, and you can drain an instance by setting its weight to zero.

Load balancer, public IP per instance

A load balancer accepts client connections on ports 21, 22 and 990 and forwards them to the instances. Each instance still has its own routable public IP and advertises it with -publicip:

Load balancer:  3.3.3.3   (ports 21, 22, 990)
Server1:        -publicip 1.1.1.1
Server2:        -publicip 2.2.2.2

Control connections arrive via 3.3.3.3; when a client goes passive, the instance hands out its own IP and the data connection bypasses the load balancer entirely.

Load balancer, no public IP per instance

If the instances have no routable addresses of their own, they must all advertise the load balancer's IP:

Load balancer:  3.3.3.3   (ports 21, 22, 990, and the passive ranges)
Server1:        -publicip 3.3.3.3
Server2:        -publicip 3.3.3.3

Now passive data connections also arrive at the load balancer, which cannot tell which instance the control connection lives on - so the load balancer must use sticky sessions by client IP, ensuring one client's control and data connections always land on the same instance. The passive port ranges (-passiveports21 / -passiveports990) must be forwarded as well.

What DocEvent itself uses

Our cloud clusters run in auto-scaling groups behind a network load balancer for initial connections, with passive data connections going directly to the instances' own addresses, plus a round-robin DNS hostname for clients that cannot handle separate connection and data addresses - the full reasoning is in Clustering recommendations. Instances drain via -shutdownwindow before leaving the cluster, the pattern described in Scaling and connection handling.

Most self-hosted customers pick DNS-based balancing: it is simple, their instance IPs are stable, and no sticky-session configuration is involved. If you are unsure which fits your network, talk to us.