Sign inSign up

rustrak/llmtrack

By rustrak

•Updated about 15 hours ago

Self-hosted LLM gateway in Rust: OpenAI-compatible API, virtual keys, budgets and spend per team

Image
API management
Machine learning & AI
Monitoring & observability
0

437

rustrak/llmtrack repository overview

⁠llmtrack

A self-hosted LLM gateway in one Rust binary. Point any OpenAI SDK at it, hand each team a virtual key, and see exactly what every one of them spent.

OpenAI- and Anthropic-compatible API in front of OpenAI, Azure OpenAI, Anthropic, Google Gemini, Groq, Mistral, DeepSeek, OpenRouter, Together, Ollama or any OpenAI-compatible server. The dashboard is inside the same image.

  • 16 MB image, amd64 and arm64, distroless, runs as non-root
  • Virtual keys and teams: budgets that reset daily, weekly or monthly, requests- and tokens-per-minute limits, model access, expiry
  • Spend tracking per request, team, key, person, customer and tag, priced from a daily-synced price list (cache and reasoning tokens priced apart)
  • Router: weighted deployments, retries, cooldowns, fallbacks
  • LiteLLM-compatible: reads x-litellm-* headers, litellm_metadata, LITELLM_MASTER_KEY and router_settings
  • Fast: +0.11 ms added p50 latency and under 90 MB of memory under load (benchmarks⁠)
  • Prompts and completions are never stored

⁠Tags

TagDatabaseUse it for
latest, vX.Y.ZSQLiteone container, nothing to provision
postgres, vX.Y.Z-postgresPostgreSQLan existing Postgres, larger installs

Pin a version (v0.1.0) in production; latest moves with every release.

⁠Quick start

docker run -d --name llmtrack -p 4000:4000 -v llmtrack_data:/data \
  -e SECRET_KEY=$(openssl rand -hex 32) \
  -e [email protected]:changeme123 \
  rustrak/llmtrack:latest

Open http://localhost:4000⁠, sign in, add a model, create a team and a key. Then call it like OpenAI:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:4000/v1", api_key="sk-…")
client.chat.completions.create(
    model="gpt-5.6",
    messages=[{"role": "user", "content": "Hello"}],
)
⁠Docker Compose
services:
  llmtrack:
    image: rustrak/llmtrack:latest
    ports: ["4000:4000"]
    volumes: [llmtrack_data:/data]
    environment:
      - SECRET_KEY=${SECRET_KEY}
      - CREATE_SUPERUSER=${CREATE_SUPERUSER}
    restart: unless-stopped

volumes:
  llmtrack_data:
⁠PostgreSQL
services:
  llmtrack:
    image: rustrak/llmtrack:postgres
    ports: ["4000:4000"]
    environment:
      - DATABASE_URL=postgres://llmtrack:llmtrack@db:5432/llmtrack
      - SECRET_KEY=${SECRET_KEY}
      - CREATE_SUPERUSER=${CREATE_SUPERUSER}
    depends_on: [db]
  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=llmtrack
      - POSTGRES_PASSWORD=llmtrack
      - POSTGRES_DB=llmtrack
    volumes: [pg_data:/var/lib/postgresql/data]

volumes:
  pg_data:

⁠Configuration

VariableRequiredWhat it does
SECRET_KEYyesAt least 64 characters (openssl rand -hex 32). Signs the session and encrypts the stored provider keys: changing it makes them unreadable
CREATE_SUPERUSERnoemail:password, the first admin, created only into an empty database
DATABASE_URLnoDefault sqlite:///data/llmtrack.db. postgres://… on the :postgres image
MASTER_KEYnosk-… bearer token for the management API, for scripts and CI. LITELLM_MASTER_KEY is read too
PORTnoDefault 4000
SSL_PROXYnotrue behind a TLS-terminating proxy: secure cookies
UPSTREAM_TIMEOUT_SECSnoHow long to wait on a silent provider, per read. Default 600
LLMTRACK_DASHBOARDnooff serves the API only
RUST_LOGnoinfo, debug, warn, error

Data lives in the /data volume. Back it up; it holds your keys, settings and usage history.

License: GPL-3.0.

Tag summary

Content type

Image

Digest

sha256:08a2fbf23…

Size

16.9 MB

Last updated

about 15 hours ago

docker pull rustrak/llmtrack