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