Architecture
How the control plane and data plane split responsibilities inside a single Express application.
llmBreakr runs as a single Express application internally split into two layers with different jobs, different auth models, and different performance requirements.
| Layer | Base path | Purpose | Auth |
|---|---|---|---|
| Control plane | /api/admin | Configuration, project/key management, audit log reads | Admin JWT |
| Data plane | /api/data | LLM proxying, streaming, limit enforcement | Virtual key |
The data plane request path
Every request to /api/data/v1/chat/completions passes through the same pipeline before it ever reaches a provider:
client request
│
▼
1. virtual key authentication → reject if invalid / revoked
│
▼
2. model resolution → is this project allowed to call this model?
│
▼
3. limit enforcement → rate limit + budget check (Redis)
│
▼
4. provider adapter → translate to OpenAI / Anthropic / Gemini shape
│
▼
5. request + usage logging → audit trail, cost tracking
│
▼
provider response (streamed back to client)Each stage can short-circuit the request — an invalid key, a disallowed model, or an exhausted budget all fail fast, before any provider is called and before any cost is incurred.
The control plane
The control plane is where admins configure everything the data plane enforces:
- Projects — logical groupings that own virtual keys and model access rules.
- Virtual keys — scoped credentials issued per project, with optional approval workflows.
- Provider credentials — encrypted at rest, added once and shared across projects that are granted access.
- RBAC — role-based permissions for who on your team can do what in the dashboard.
- Audit log — every admin action and every chat request is recorded.
Tech stack
| Layer | Technology |
|---|---|
| API server | Node.js 18+, Express |
| Persistence | MySQL via Sequelize ORM |
| Rate limiting / cache | Redis |
| Dashboard | Next.js 15, React 19, Tailwind CSS |
| Deployment | Docker / Docker Compose |
Why this split matters
Keeping configuration (control plane) and traffic (data plane) as distinct concerns — with different auth models — means the hot path for every LLM call stays small and fast, while admin operations can carry heavier checks (JWT verification, RBAC, audit writes) without touching request latency.
It also means llmBreakr only needs two external dependencies to run: MySQL and Redis. No bundled message queue, no vector store, no extra services — the gateway stays lightweight enough to run next to whatever you're already operating.