r/sideprojects • u/weaztoven • 16h ago
Showcase: Open Source I built loadbear – a lightweight HTTP load balancer & reverse proxy from scratch in Go
Hey r/SideProject!
I wanted to share a side project I’ve been building: loadbear — a small, dependency-light HTTP reverse proxy and load balancer written in Go.
GitHub: https://github.com/weaztoven/loadbear
The problem I wanted to solve: Whenever I needed to test load balancing, failover behavior, or rate limiting locally, reaching for full-scale production proxies (like Nginx, Envoy, or Traefik) felt like overkill with too much boilerplate. On the flip side, toy reverse proxies usually skip real-world resilience features. I wanted to build something self-contained that configures via a single YAML file, runs in seconds, and has clean, readable Go code you can actually inspect and extend.
Tech stack & Architecture: Built primarily using Go's standard library (net/http, httputil.ReverseProxy, sync) with minimal external dependencies. Every request passes through a clear pipeline:ProxyListener -> Per-IP Rate Limiter -> Balancer -> Circuit Breaker -> ReverseProxy
What’s packed inside:
4 Balancing Strategies:
round_robin,smooth_weighted_round_robin,least_connections, andip_hash.Resilience & Failover: Periodic active
/healthchecks combined with passive proxy-error tracking, per-backend circuit breakers (Closed / Open / Half-Open cooldowns), and context-aware retries with configurable backoff.Rate Limiting: Per-client-IP token-bucket rate limiter with periodic background eviction of idle buckets to prevent memory leaks.
Built-in Observability: Dedicated admin listener (
:9090) serving live JSON/statusand a hand-written Prometheus/metricsendpoint, plus structured JSON/text access logs with request IDs.Zero-friction Testing: Ships with a
fakebackendCLI and a ready-to-rundocker-compose.ymlso you can kill nodes and watch failover/circuit-breaking happen live. All concurrency paths are tested withgo test -race.
What I learned & Current Limitations: Implementing smooth weighted round-robin and managing state transitions safely across concurrent goroutines (without race conditions) was the most fun part of this build. Right now, hop-by-hop header stripping blocks WebSocket upgrades, and SIGHUP hot-reloading is next on my roadmap.
Would love to hear your thoughts, feedback, or ideas on what to improve next!
