A production-grade AI gateway for OpenAI-compatible APIs with intelligent provider failover, automatic recovery, circuit breaking, semantic caching, tenant-aware rate limiting, and enterprise observability.
Frontend console |
Successful chat |
Grafana dashboard |
Chaos demo |
LLM Gateway is a reliability focused proxy for chat completion traffic. It exposes an OpenAI compatible API while routing requests across multiple configured providers. The gateway stores custom provider credentials in Redis with encrypted API keys, tracks provider health in sliding windows, opens circuits when a provider degrades, and reroutes traffic to healthier providers.
The project also includes a Next.js console for saving providers, sending chat requests, injecting chaos, and opening the monitoring tools.
| OpenAI compatible API | Clients can point chat completion traffic at the gateway with a base URL change. |
| Provider routing | LiteLLM normalizes calls across configured OpenAI compatible providers. |
| Encrypted provider storage | Custom providers are persisted in Redis and API keys are encrypted with Fernet. |
| Health tracking | Redis sliding windows track success rate, p50 latency, p95 latency, p99 latency, and error type. |
| Circuit breaking | Providers move through closed, open, and half open states based on health thresholds. |
| Retry queue | Deferrable requests can move into a Redis queue with backoff, jitter, and idempotency. |
| Semantic cache | Repeated prompts can be served from Redis using normalized prompt hashes. |
| Tenant controls | Per tenant rate limits, monthly budgets, request logging, and PII redaction are included. |
| Observability | Prometheus metrics and a provisioned Grafana dashboard show traffic, errors, latency, circuit state, queue depth, and cost. |
frontend |
Next.js console for provider setup, chat testing, chaos actions, and monitoring links. |
backend/app/main.py |
FastAPI app with chat, provider admin, health, readiness, docs, and metrics routes. |
backend/app/providers.py |
Provider selection, LiteLLM calls, failover, hedging, queue handoff, and metrics. |
backend/app/runtime_config.py |
Redis provider store with encrypted API keys. |
backend/app/health.py |
Redis sliding window provider health tracker. |
backend/app/circuit_breaker.py |
Provider circuit breaker state machine. |
backend/app/queue.py |
Redis retry queue with idempotency protection. |
backend/app/chaos.py |
Admin chaos injection for synthetic provider latency and errors. |
monitoring |
Prometheus and Grafana provisioning. |
From the project root, build the containers:
docker compose buildStart the stack:
docker compose upOpen these services:
| Frontend console | http://localhost:3001 |
| Backend API | http://localhost:8000 |
| API docs | http://localhost:8000/docs |
| Grafana | http://localhost:3000 |
| Prometheus | http://localhost:9090 |
To stop the stack:
docker compose downCreate your local environment file:
copy .env.example .envSet the values that apply to your machine:
LLM_GATEWAY_ADMIN_API_KEY=your_admin_key
LLM_GATEWAY_METRICS_API_KEY=your_metrics_key
ENCRYPTION_KEY=your_fernet_key
LLM_GATEWAY_REDIS_URL=redis://redis:6379/0
LLM_GATEWAY_ENABLE_DOCS=trueNever commit real API keys. The local .env file is ignored by Git.
Open the console:
http://localhost:3001
Enter the admin key from your environment. Then use the provider form to save a custom OpenAI compatible API.
Example provider values:
Provider name: logfare
Model: openai/deepseek_v4_flash
API base URL: https://logfare.ai/v1
API key: your_api_key
Request classes: classification
Priority: 1
Enabled: checked
After saving the provider, send a chat request from the chat panel. The browser talks to the gateway, and the gateway calls the provider.
Any API that follows the OpenAI chat completion shape can be used.
For a hosted provider:
API base URL: https://your_provider.example.com/v1
Model: openai/your_model
API key: your_api_key
For a local model server running on your computer while the backend runs in a container:
API base URL: http://host.docker.internal:11434/v1
Model: openai/your_model
API key: local
Use host.docker.internal because localhost inside the backend container points to the container itself.
Prometheus scrapes the gateway metrics endpoint. Grafana is provisioned with a dashboard for:
| RPS by provider | Error rate |
| p95 latency | Circuit state timeline |
| Failover events | Queue depth |
| Cost per hour by tenant and feature | Provider health at a glance |
Use the frontend console to trigger provider chaos:
- Start the stack.
- Open the frontend console.
- Save or select a provider.
- Send a healthy chat request.
- Open Grafana.
- Click the Chaos action for the provider.
- Send more chat requests.
- Watch errors rise, the circuit open, and traffic reroute.
- Wait for recovery and confirm the provider closes again.
The backend exposes:
http://localhost:8000/health
http://localhost:8000/ready
The health route confirms the process is alive. The ready route confirms Redis is reachable and at least one provider route can be used.
Activate the virtual environment:
.\venv\Scripts\Activate.ps1Run the test suite:
pytest backend\testsThe tests cover health tracking, circuit breaker cycles, deferrable queue behavior, semantic cache, tenant limits, PII redaction, runtime provider encryption, and production hardening.
Pytest cache is stored in:
.tmp/pytest_cache
This usually means no provider is available. Confirm that a provider is saved, enabled, mapped to the request class, and not blocked by an open circuit.
Do not delete Docker volumes if you want Redis data to stay. Use normal container restart commands for everyday development.
When the backend runs in a container, use host.docker.internal instead of localhost for services running on your computer.
Use the admin key configured in LLM_GATEWAY_ADMIN_API_KEY.
This project is suitable as a portfolio grade implementation and local demo. Before production use, add managed secret storage, deployment specific identity controls, persistent Redis backups, stricter network policy, CI checks, and a full operational runbook.
MIT License. See LICENSE.




