⚡ LLM Gateway & Circuit Breaker
A high-throughput, distributed LLM Gateway and Circuit Breaker designed to protect AI agents, async workers, and microservices from upstream LLM provider outages, rate limits ($429$), and latency spikes.
🌟 Key Features
- 🛡️ Atomic Redis Circuit Breaker (FSM): Lock-free finite state machine (
CLOSED→OPEN→HALF_OPEN) powered by single-roundtrip Redis Lua scripts with probe throttling and clock-skew protection. - ⏱️ Dual-Budget Distributed Rate Limiter: Atomic token bucket tracking both Requests Per Minute (RPM) and Tokens Per Minute (TPM) with $O(1)$ token estimation and all-or-nothing consumption.
- 🔀 Resilient Routing & Fallback Chains: Multi-tier failover chains across primary and secondary providers with safe pre-yield streaming failovers.
- ⚡ Tiered Caching Layer:
- Tier 1: Sub-millisecond deterministic SHA-256 exact match cache in Redis.
- Tier 2: Local semantic similarity cache using
fastembedONNX embeddings (no external API calls to check cache).
- 🔌 Unified Provider Adapters: Native connection pooling and normalized OpenAI completion shapes for OpenAI, Anthropic, Azure OpenAI, Ollama, and Mock/Offline.
- 📊 Prometheus Metrics & Observability: Real-time histograms and counters for request latencies, status codes, and provider health.
- 📦 Dual Distribution: Use as an embedded Python Library or run as a standalone FastAPI Docker Proxy.
🏗️ System Architecture
┌───────────────────────────────┐
│ Client Request (OpenAI SDK) │
└───────────────┬───────────────┘
│
[ Auth & Metrics ]
│
▼
┌─────────────────────────┐
│ Gateway Router │
└────────────┬────────────┘
│
┌────────────────────────────────┴────────────────────────────────┐
│ │
▼ ▼
┌────────────────────┐ ┌───────────────────┐
│ Exact Match │──(Cache Hit)──► [ Return Cached Response ] │ Semantic Cache │
│ SHA-256 Cache │ │ (fastembed ONNX) │
└────────────────────┘ └───────────────────┘
│ (Cache Miss)
▼
┌────────────────────┐
│ Circuit Breaker │──(Open / Tripped)──► [ Fast 503 Rejection / Cascade Fallback ]
│ Atomic Lua Script │
└──────────┬─────────┘
│ (Allowed)
▼
┌────────────────────┐
│ Rate Limiter Bucket│──(Exceeded)────────► [ 429 / Cascade Fallback ]
│ (RPM + TPM Budget)│
└──────────┬─────────┘
│ (Granted)
▼
┌─────────────────────────────────────────────────────────────┐
│ Provider Dispatch │
│ [Primary: OpenAI] ──► (Fail) ──► [Fallback: Anthropic] │
└─────────────────────────────────────────────────────────────┘
📦 Installation
As a Python Library
# Core library
pip install llm-gateway
# With FastAPI standalone proxy dependencies
pip install "llm-gateway[proxy]"
# With local ONNX semantic cache dependencies
pip install "llm-gateway[semantic-cache]"
# With full development & test suite
pip install "llm-gateway[dev,proxy,semantic-cache]"
🚀 Quick Start
1. Using as a Python Library (Direct Asyncio)
import asyncio
from llm_gateway import GatewayConfig, GatewayRouter
from llm_gateway.core.providers.base import ChatCompletionRequest, ChatMessage
async def main():
# 1. Define configuration with fallback routes
config = GatewayConfig(
providers={
"openai-main": {
"type": "openai",
"api_key": "sk-...",
"default_model": "gpt-4o",
"circuit_breaker": {"failure_threshold": 3, "recovery_timeout_s": 30},
"rate_limit": {"rpm": 500, "tpm": 100000},
},
"anthropic-fallback": {
"type": "anthropic",
"api_key": "sk-ant-...",
"default_model": "claude-3-5-sonnet-20241022",
},
},
routes={
"default": {
"primary": "openai-main",
"fallbacks": ["anthropic-fallback"],
}
},
redis={"url": "redis://localhost:6379/0", "fail_open": True},
)
# 2. Instantiate router
router = GatewayRouter(config)
# 3. Dispatch chat completion
req = ChatCompletionRequest(
model="gpt-4o",
messages=[ChatMessage(role="user", content="Explain quantum computing in 10 words.")],
)
response = await router.route(req, route_name="default")
print(response.choices[0].message.content)
await router.close()
if __name__ == "__main__":
asyncio.run(main())
2. Running as a Standalone Docker Proxy
Step 1: Create your gateway.yaml
providers:
openai:
type: openai
api_key: "${OPENAI_API_KEY}"
default_model: gpt-4o
circuit_breaker:
failure_threshold: 3
recovery_timeout_s: 30
rate_limit:
rpm: 1000
tpm: 200000
anthropic:
type: anthropic
api_key: "${ANTHROPIC_API_KEY}"
default_model: claude-3-5-sonnet-20241022
mock-offline:
type: mock
default_model: mock-gpt-4o
mock_response: "Hello from local mock LLM!"
routes:
default:
primary: openai
fallbacks: [anthropic, mock-offline]
redis:
url: "redis://localhost:6379/0"
fail_open: true
auth:
enabled: false
Step 2: Start the Stack with Docker Compose
docker compose up --build
- LLM Gateway Endpoint:
http://localhost:8000 - Prometheus Metrics:
http://localhost:9090
Step 3: Call with the OpenAI SDK
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="any-string", # or your Bearer token if auth.enabled is true
)
response = client.chat.completions.create(
model="default",
messages=[{"role": "user", "content": "Hello LLM Gateway!"}],
)
print(response.choices[0].message.content)
📡 API Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST |
/v1/chat/completions |
OpenAI-compatible chat completion (supports JSON & SSE streaming stream=true) |
GET |
/v1/models |
List all available gateway routes and default models |
GET |
/health/live |
Liveness probe (Kubernetes / Docker) |
GET |
/health/ready |
Readiness probe (verifies provider connectivity) |
GET |
/metrics |
Prometheus metrics exporter |
⚙️ Configuration Reference
| Parameter | Environment Variable | Default | Description |
|---|---|---|---|
redis.url |
LLM_GATEWAY__REDIS__URL / REDIS_URL |
redis://localhost:6379/0 |
Redis connection URI |
redis.fail_open |
LLM_GATEWAY__REDIS__FAIL_OPEN |
true |
When true, gateway continues operating if Redis is unreachable |
auth.enabled |
LLM_GATEWAY__AUTH__ENABLED |
false |
Enable static Bearer token authentication |
auth.tokens |
LLM_GATEWAY__AUTH__TOKENS |
[] |
List of authorized Bearer tokens |
cache.exact_ttl_s |
LLM_GATEWAY__CACHE__EXACT_TTL_S |
3600 |
Exact-match cache TTL in seconds |
cache.semantic_threshold |
LLM_GATEWAY__CACHE__SEMANTIC_THRESHOLD |
0.92 |
Cosine similarity threshold for semantic cache hits |
🧪 Testing & Load Benchmarking
Automated Test Suite
# Run all 209 unit, integration, and load tests
pytest tests/unit/ tests/integration/ tests/load/ --cov=llm_gateway
Live Concurrency & Stress Testing
# Non-streaming stress test (1,000 requests, 50 concurrent workers)
python3 stress_test.py -n 1000 -c 50
# Streaming SSE stress test (200 requests, 20 concurrent workers)
python3 stress_test.py -n 200 -c 20 --stream
Export OpenAPI & JSON Schemas
python3 scripts/export_schema.py --all ./schemas
📄 License
This project is licensed under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file resilient_llm_gateway-0.1.0.tar.gz.
File metadata
- Download URL: resilient_llm_gateway-0.1.0.tar.gz
- Upload date:
- Size: 78.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5d831e4b329fd67a40a32da83c669c9926d0f1b548780d408ebcc1a676f9148
|
|
| MD5 |
bb32c7b411530f7438c0c435bb2994aa
|
|
| BLAKE2b-256 |
c7be77cc2d9ff81c2a0f807fea07b51026ce4602449ca4c9440c6eea36488832
|
File details
Details for the file resilient_llm_gateway-0.1.0-py3-none-any.whl.
File metadata
- Download URL: resilient_llm_gateway-0.1.0-py3-none-any.whl
- Upload date:
- Size: 60.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dc282991ddaaecd9112e4f42bf1003ec29ad98ceb7d4b37ea59a350f62d3f25
|
|
| MD5 |
83635c8aea49337da928ca3264cc847d
|
|
| BLAKE2b-256 |
018925cd317c43f3cf33bfc345c22cec90d557a6bbbf4b8649df49a6a068ae26
|