Your whole production edge.
One binary. One YAML file.
Reverse proxy, automatic HTTPS, health-checked failover, per-IP abuse protection, and VRRP self-HA — the stack that's usually nginx + certbot + keepalived + fail2ban, as a single memory-safe Rust binary built on Cloudflare's Pingora.
Nobody's production edge is just a proxy
Run one seriously and count the daemons: a proxy, a cert renewer on a cron, a failover manager, a ban list scraping your logs — plus the glue keeping their configs in agreement at 3 a.m.
omlb collapses that whole column into one Rust process and one
file — no GC pauses, no C footguns, and a --check that proves the
config is sound before it ships.
Everything the edge needs, nothing bolted on
L7 proxy on Pingora
HTTP/1.1 and HTTP/2 with TLS termination, SNI routing, and pooled upstream connections. Restarts hand off sockets gracefully, so deploys drop nothing.
Automatic HTTPS
Certificates issue themselves, renew themselves, and slide into the live cert store mid-flight. You will not miss certbot.
Real load balancing
Weighted round-robin, random, two-choices least-conn, or Ketama consistent hashing — chosen per pool, weighted per backend.
Failover that fails over
Active probes catch dead backends. Passive outlier detection catches dying ones mid-traffic. Retries make sure clients never have to care.
Edge security gate
Rate limits per IP, instant bans for anyone touching /.env or wp-login.php, optional 404-strike bans — all judged before routing even runs.
VRRP self-HA
Two nodes, UDP heartbeats, one floating IP. The master dies, the backup takes the address in seconds — keepalived's job, retired.
Live configuration
One schema-checked YAML with env overrides on top. Edit it and the change swaps in atomically mid-traffic — or gets refused whole.
Response caching
Per-route opt-in: cacheable GETs answer from a bounded in-memory LRU and never wake the upstream — or the filter chain.
L4 (TCP) proxying
Raw TCP when you need it — IRC, Postgres, anything — with TLS termination or TLS-to-backend as one-flag options.
Managed pools
Hand a pool a Docker label and it keeps N replicas healthy, replacing containers that hang while alive — the failure a restart: policy never sees.
Pluggable filters
Six native Rust filters for the always-on work, plus sandboxed WASM plugins you can load at runtime when you need something custom (experimental).
Observability
Prometheus metrics, structured JSON or journald logs, an admin API, and a built-in dashboard — all reading counters off the hot path.
Readable in one sitting, validated before it ships
- Automatic HTTPS with hot cert swap
- p2c load balancing + health-checked failover
- Scanner bans, inline, before routing
- IPv4 and IPv6, one flag
-
omlb --checkin CI — a typo'd key is a hard error - Hot reload with a connection-preserving atomic swap
That's the entire config for an HTTPS edge with failover and abuse protection. See every mode →
tls:
acme:
enabled: true
contacts: ["mailto:you@example.com"]
terms_of_service_agreed: true
domains: [example.com]
listeners:
- { name: https, address: "0.0.0.0:443", tls: { managed: true }, http2: true, ipv6: true }
upstreams:
app:
algorithm: power_of_two
backends: [{ addr: "10.0.0.1:8080" }, { addr: "10.0.0.2:8080" }]
health_check: { kind: http, path: /healthz }
routes:
- { name: app, match: { host: example.com }, upstream: app }
security:
enabled: true
rate_limit_rps: 100
ban_paths: [/.env, /.git/, /wp-login.php] Where it's fast — and where nginx still wins
Loopback micro-benchmarks, CPU-pinned, median of 3 runs. They measure proxy overhead, not your network — ratios are the point. Full methodology →
L7 throughput & latency
| target | req/s | p50 | p99 |
|---|---|---|---|
| direct to backend | ~97,000 | 0.51 ms | 2.5 ms |
| omlb | ~62,000 | 0.94 ms | 3.0 ms |
| nginx | ~78,000 | 0.60 ms | 3.7 ms |
nginx leads raw RPS by ~25% — a decade-tuned C proxy should. omlb lands in the same order of magnitude with sub-millisecond added median latency and a slightly tighter p99, while carrying features nginx needs three extra daemons for.
Failover & cache
| scenario | result |
|---|---|
| VRRP: kill master → backup owns VIP | ~1.5 s |
| cache HIT vs proxied | ~137k vs ~92k req/s |
| native filter overhead | ~14% of baseline |
| WASM plugin, pooled isolation | ~61% of baseline |
Failover detection is bounded by dead_multiplier × advert_interval —
the same knob keepalived exposes. Cache hits are decoupled from the backend
entirely; with a real origin the gap is far larger.
What it can't do (yet)
Young project, clearly marked edges — better you read them here than discover them mid-incident.
- ACME is HTTP-01 only — wildcards need DNS-01, which isn't there yet — bring your own wildcard cert
- No HTTP/3 (QUIC) — HTTP/1.1 and HTTP/2 are the menu
- No mTLS client auth — TLS authenticates the server, not the client, for now
- No live service discovery — backends come from your config, not from Consul, DNS-SRV, or Kubernetes
- Literal matching — exact hosts and path prefixes — the regex engine you might want isn't here
- Per-instance ban state — each HA node keeps its own ban table; they don't gossip
- Topology changes need a restart — a graceful one — but refused on hot reload rather than half-applied
- No distributed tracing yet — metrics and logs today; OpenTelemetry spans aren't wired up
If the goal is retiring the classic four-daemon HTTPS edge, none of these will stop you. If one of them would, pick something else honestly →
Running the edge at ananaslabs.eu — today
It replaced a Caddy deployment outright — and the page you're reading came through it.