Overview
Fairvisor Edge is an inline HTTP policy enforcement point built on OpenResty/LuaJIT.
Fairvisor Edge is an inline HTTP policy enforcement point built on OpenResty / LuaJIT. It evaluates request policies with sub-millisecond latency and returns allow / reject / throttle decisions with structured rate-limit headers and Prometheus metrics.
What Fairvisor is
Fairvisor sits between your gateway and upstream API (or LLM provider) and enforces a declarative policy bundle on every request. It is not a reverse proxy or WAF by default — it operates as a sidecar decision service (decision_service mode) that your existing gateway calls via auth_request or ext_authz, or as a transparent proxy (reverse_proxy mode).
Client
└─→ Gateway (nginx / Envoy / Kong / Traefik)
└─→ Fairvisor Edge ← policy bundle
└─→ Upstream / LLM Provider
Core capabilities
| Capability | Description |
|---|---|
| Token Bucket | Per-key request-rate limiting with configurable burst |
| Cost-Based Budget | Period spend quotas (5m/hourly/daily/weekly) with staged warn/throttle/reject |
| LLM Token Limiting | Per-minute and per-day token budgets with pessimistic reservation and post-response reconciliation |
| Budget Circuit Breaker | Trips when spend rate exceeds a per-minute threshold, auto-resets |
| Loop Detection | Blocks repeated identical requests (agentic loop protection) |
| Kill Switch | Instant traffic block matched on any descriptor, with optional TTL |
| Shadow Mode | Dry-run enforcement: tracks would-reject without blocking traffic |
| Streaming Enforcement | Mid-stream SSE truncation when completion token budget is exceeded |
| SaaS Control Plane | Push/pull policy updates, heartbeat, and event delivery via SaaS API |
Runtime
- Language: Lua 5.1 / LuaJIT 2.1+
- Platform: OpenResty 1.25.3.2 (nginx with embedded Lua)
- State storage:
ngx.shared.dict(shared memory, no external dependency required) - Distributed limiting: not supported in current OSS runtime (state is local to each edge instance)
Counters are not shared across replicas. Limiter state lives in ngx.shared.dict — local to each edge process. Multiple instances do not coordinate. Distributed state (Redis-backed) is planned post-MVP. If you need cross-instance enforcement today, route a given tenant's traffic to a single replica.
Architecture overview
nginx worker
├── init_worker_by_lua
│ ├── load env config
│ ├── load policy bundle (file or SaaS)
│ └── start timers (hot-reload, heartbeat, event flush)
│
└── per-request hot path
├── access_handler()
│ ├── build_request_context() ← headers, JWT, IP, UA
│ ├── rule_engine.evaluate()
│ │ ├── kill_switch.check()
│ │ ├── route_index.match()
│ │ └── per-policy:
│ │ ├── loop_detector.check()
│ │ ├── circuit_breaker.check()
│ │ └── per-rule limiter
│ └── set response headers / return 429
└── body_filter (streaming mode only)
└── streaming.body_filter()
Getting started
- Quickstart — running in Docker in 5 minutes
- CLI reference —
fairvisor init,validate,test,connect - Policy format — full bundle schema
- SaaS connection — connecting to the control plane