Load balancing

Balance two upstreams

Send traffic to two backend instances and observe Caddy’s upstream selection.

10 minute lesson

~~~

A load balancer chooses an available upstream for each request. That’s the whole job: one incoming stream of requests, several backends, a selection decision per request. In Caddy, you get one by giving reverse_proxy more than one upstream address.

Configure both backends

With both loopback backends from the first lesson running:

reverse_proxy 127.0.0.1:4001 127.0.0.1:4002

That’s the entire change. Caddy’s default selection policy is random — each request picks an upstream at random. The default policy is suitable for many stateless labs, but policy must match application behavior, which the next lesson digs into.

Observe the distribution

Our backends report their port in every response, so distribution is measurable. Send repeated requests and count each backend port in the responses:

for i in {1..20}; do
  curl --silent http://127.0.0.1:8080/ | grep -o '"port":[0-9]*'
done | sort | uniq -c
#  11 "port":4001
#   9 "port":4002

Roughly even, not exactly even — it’s random selection, not strict alternation. The point isn’t the exact split. The point is that you measured it instead of assuming it, a habit that pays off when a policy misbehaves in production.

Kill one backend

Now stop the 4002 process and run the loop again:

#  13 "port":4001
#   7 failed

About half your requests fail with 502. Caddy doesn’t yet know 4002 is dead — it keeps selecting it and hitting a connection error each time. Record failures before health policy is added: this is the baseline that health checks (two lessons from now) exist to fix, and seeing the failure rate first makes the fix meaningful.

Restart the backend and confirm both ports reappear in the counts.

What this doesn’t buy you

Two upstreams on one laptop demonstrate selection mechanics, nothing more. Two processes are not high availability if they share the same failing machine, storage, configuration, and release. Real redundancy separates failure domains — different hosts at minimum, and the same thinking applied to whatever database both instances share. A load balancer distributes requests; it can’t distribute away a single point of failure sitting behind both upstreams.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →