Routing

Five ways to pick a backend, all configured with one line.

Round-Robin

Requests go to each backend in turn. With three servers, each one gets every third request. This is the default.

Weighted Round-Robin

Give a bigger machine a bigger share. A backend with weight: 3 takes three requests out of every five — exactly, not on average.

Least Connections

New requests go to whichever backend is currently handling the fewest. Better than round-robin when some requests take much longer than others.

Random

Pick a healthy backend at random. Cheap, and it spreads load well over a large number of requests.

IP Hash

The same visitor keeps landing on the same backend, so their session or cache entry stays put. Stable as long as the backend list does not change.

HTTP Reverse Proxy

A plain HTTP proxy. Request and response bodies stream through rather than being buffered, and the client's address is forwarded in X-Forwarded-For.

Keeping traffic on working servers

What happens when a backend stops answering.

Health Checks

Haribon probes each backend on an interval and takes it out of rotation after a set number of failures. It goes back in automatically once it passes again. Nothing else has to know.

Circuit Breaker

A per-backend breaker for failures your probes never see — a backend that answers, but answers with a 500 every time. After enough failures the breaker opens and requests stop going there for a cooldown period.

Retries, Only Where Safe

A connection failure is retried on another backend, but only when the method is safe to repeat. POST and PATCH are never retried for you, because a retried payment is worse than a failed one.

Readiness That Means Something

/healthz says the process is alive. /readyz says it has somewhere to send traffic, and returns 503 when every backend is down — so an orchestrator stops routing to a pod that cannot serve.

Graceful Shutdown

On shutdown, Haribon stops accepting new connections and waits for in-flight requests to finish before exiting, up to a configurable timeout.

Config Checker

haribon check reports anything contradictory in a config file and exits 0 or 1. haribon validate goes further and checks it against a JSON schema, catching misspelled keys. Both are safe in CI.

Changing without restarting

The backend list does not have to be frozen at startup.

File Discovery

Point Haribon at a JSON array of backend URLs that another system rewrites. New servers join and dead ones leave while Haribon runs.

DNS Discovery

Read the backend list from DNS, so a Kubernetes Service or an autoscaling group can hand you servers without a restart. A and AAAA records; SRV is not supported.

Config Hot Reload

Change anything in the config file — strategies, thresholds, timeouts, backends — and Haribon picks it up. Breaker history survives, so a reload does not reset a breaker that is mid-cooldown.

Clustering

Run more than one Haribon and they compare notes over UDP. A server one replica cannot reach is skipped by all of them. There is no separate coordination service to run and no leader to elect.

Seeing what happened

Logs and metrics in formats your existing pipeline already understands.

Prometheus Metrics

A /metrics endpoint in the standard text format. Per-backend request counts, retries, last response time, health, breaker state, and active connections.

Structured Logs

One JSON object per request: time, method, path, chosen backend, status, duration, and how many times it was retried. log_format: text gives you a human-readable line instead.

Log Exporting

Send logs to Loki, Elasticsearch, or Fluent Bit in addition to stdout and a file. Each destination batches in the background, so a slow collector does not slow down your traffic.

Docker Support

Official images on GitHub Container Registry, plus Compose files for a local cluster and for a full Grafana, Loki, and Promtail stack.

Configuration

One YAML file. Nothing else to install.

One Dependency

Everything is the Go standard library plus a YAML parser. The result is a single static binary with no runtime to install.

Environment Overrides

HARIBON_HOST, HARIBON_PORT, and HARIBON_CONFIG override the corresponding settings, which is usually what you want in a container.

Values From the Environment

Anything in the config file can reference ${VAR} and be filled in at startup — the usual trick for giving each replica a unique node_id.

JSON Schema

schema/haribon-config.schema.json describes the whole file, so your editor can complete and check it as you type. haribon validate uses the same schema.

Not here yet

Listed so you can plan around them rather than discover them.

Haribon does not terminate TLS, does not trace requests, and does not rate-limit. It does not host virtual hosts or route by hostname or path — every request goes to the backend pool. There is no management UI or admin API: the admin: block in the config file is read but nothing listens on it. These are tracked in ROADMAP.md.