Skip to content

Go Load Balancer

2025Public, finished

A small HTTP load balancer and dashboard in Go, built to understand what a reverse proxy actually does before trusting one.

RoleBuilt it to learn

Timeline
2025
Stack
Go, net/http, httputil

I'd used load balancers for years without building one. This is the smallest version I could write that still does the real jobs: spread requests across backends, notice when one dies, and stop sending it traffic.

It has three parts: the balancer, a toy backend server, and a dashboard for watching and poking at both.

What it does

  • Round-robin selection across healthy backends, behind a mutex, with httputil.ReverseProxy doing the proxying.
  • Health checks every 30 seconds: a TCP dial with a three-second timeout. A backend that fails is skipped until it answers again.
  • Server timeouts for reads, writes and idle connections, and a graceful shutdown that gives in-flight requests a few seconds to finish.
  • A dashboard that polls a status endpoint, shows each backend's health and response times, and lets you mark a backend as not ready, which is how you'd take one out for maintenance.

Locking, health checks and shutdown

Every request reads the health state, and the checker writes it once every thirty seconds. For that read-heavy pattern a read-write mutex fits better than a channel, and it's easier to reason about.

A TCP check tells you less than I'd hoped. A port that accepts connections can still be returning errors, so a production balancer should check an HTTP health endpoint and ideally watch real responses too. Finding that gap was the main reason building this was worth it.

Without graceful shutdown, every deploy drops whatever requests were in flight.

End of case study.

Next projectCogitatorA local code search engine in about 500 lines of OCaml: TF-IDF over code chunks, ranked by cosine similarity, printed as context for an LLM.