DEV Community

Cover image for I built a reverse proxy load balancer in Go (with health checks + failover)
Sin
Sin

Posted on

I built a reverse proxy load balancer in Go (with health checks + failover)

I wanted to understand how real load balancers work under the hood, so I built one in Go using only the standard library.

A minimal implementation that still incorporates essential building blocks of production-style load balancers:

  • Reverse proxy using httputil.ReverseProxy
  • Atomic round-robin load balancing (no mutex)
  • Active health checks (runs every 10s, concurrent probing)
  • Automatic failover + retry on backend failure
  • Structured request logging
  • Skips unhealthy backends dynamically

Architecture:

Client → Load Balancer (:8080) → Backend servers (:9001, :9002, :9003)

How it works:

  • Each request is forwarded through a reverse proxy
  • A global atomic counter distributes traffic (round-robin)
  • Health checker continuously probes /health on each backend
  • If a backend fails → it’s marked down and skipped
  • Proxy retries request on the next available backend

One thing I found interesting:
Go’s httputil.ReverseProxy gives you hooks like ErrorHandler, which makes it possible to implement retry/failover cleanly before any response is sent.

Example behavior:

  • Kill one backend → traffic automatically reroutes
  • Restart it → it gets picked up again after health check

Everything is built with Go stdlib — no frameworks, no external deps.

Repo:
https://github.com/pigglegiggle/load_balancer

Would love feedback on:

  • architecture decisions
  • better load balancing strategies (least connections, etc.)
  • production improvements

Top comments (0)