The LLM Interactive Proxy uses a unified database abstraction layer based on SQLAlchemy and SQLModel. This provides portable, dialect-agnostic database access with support for multiple database backends.
The proxy stores various operational data in a database:
- Session Summaries (ProxyMem): Cross-session memory and context
- SSO Authentication: Agent tokens, pending authorizations, rate limits
- User Project Mappings: Stable project IDs for memory isolation
By default, the proxy uses SQLite which requires no additional setup. For production deployments or multi-instance setups, PostgreSQL is recommended.
SQLite is the default database and works out of the box:
# Just start the proxy - SQLite database will be created automatically
python -m src.core.cliThe database file will be created at ./var/db/proxy.db.
For PostgreSQL, set the database URL:
# Via environment variable
export DATABASE_URL="postgresql+asyncpg://user:password@localhost:5432/llm_proxy"
# Or via CLI flag
python -m src.core.cli --database-url "postgresql+asyncpg://user:password@localhost:5432/llm_proxy"# Database connection URL
export DATABASE_URL="sqlite+aiosqlite:///./var/db/proxy.db"
# Connection pool settings (PostgreSQL only)
export DATABASE_POOL_SIZE=5
export DATABASE_MAX_OVERFLOW=10
export DATABASE_POOL_TIMEOUT=30
# Debug settings
export DATABASE_ECHO=false
export DATABASE_ECHO_POOL=false
# Migration settings
export DATABASE_AUTO_MIGRATE=truepython -m src.core.cli \
--database-url "postgresql+asyncpg://user:pass@localhost/db" \
--database-pool-size 10 \
--database-max-overflow 20 \
--database-echoAdd database settings to your config.yaml:
database:
# SQLite (default)
url: "sqlite+aiosqlite:///./var/db/proxy.db"
# Connection pool (ignored for SQLite)
pool_size: 5
max_overflow: 10
pool_timeout: 30
# Debug logging
echo: false
echo_pool: false
# Auto-run migrations on startup
auto_migrate: trueThe database URL follows SQLAlchemy's URL format:
dialect+driver://username:password@host:port/database
# Relative path (recommended for development)
sqlite+aiosqlite:///./var/db/proxy.db
# Absolute path
sqlite+aiosqlite:////absolute/path/to/db/proxy.db
# In-memory database (for testing only)
sqlite+aiosqlite:///:memory:# Basic connection
postgresql+asyncpg://user:password@localhost:5432/llm_proxy
# With SSL
postgresql+asyncpg://user:password@host:5432/db?ssl=require
# Unix socket connection
postgresql+asyncpg://user:password@/db?host=/var/run/postgresql
# Connection with options
postgresql+asyncpg://user:password@host/db?connect_timeout=10| Option | Type | Default | Description |
|---|---|---|---|
url |
string | sqlite+aiosqlite:///./var/db/proxy.db |
Database connection URL |
pool_size |
int | 5 |
Connection pool size (1-100) |
max_overflow |
int | 10 |
Extra connections beyond pool_size (0-100) |
pool_timeout |
int | 30 |
Seconds to wait for a connection |
echo |
bool | false |
Log SQL statements |
echo_pool |
bool | false |
Log connection pool events |
auto_migrate |
bool | true |
Run migrations on startup |
Best for:
- Development and testing
- Single-instance deployments
- Personal proxy installations
- Low-to-moderate traffic
Advantages:
- Zero configuration required
- No external dependencies
- File-based, easy to backup
- Sufficient for most personal use cases
Limitations:
- Single writer at a time
- Not suitable for multi-instance deployments
- Limited concurrent connections
Best for:
- Production deployments
- Multi-instance/load-balanced setups
- High-traffic environments
- Team/enterprise deployments
Advantages:
- Full ACID compliance
- Excellent concurrency support
- Advanced features (JSONB, full-text search)
- Connection pooling
Requirements:
- PostgreSQL 12+ server
asyncpgdriver (included in dependencies)
-- Create database
CREATE DATABASE llm_proxy;
-- Create user with password
CREATE USER llm_proxy_user WITH PASSWORD 'secure_password';
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE llm_proxy TO llm_proxy_user;database:
url: "postgresql+asyncpg://llm_proxy_user:secure_password@localhost:5432/llm_proxy"
pool_size: 10
max_overflow: 20For production PostgreSQL deployments:
database:
url: "postgresql+asyncpg://user:pass@host:5432/db"
# Pool size = 2 * CPU cores is a good starting point
pool_size: 10
# Allow overflow for traffic spikes
max_overflow: 20
# Reasonable timeout
pool_timeout: 30The proxy uses Alembic for database migrations. By default, migrations run automatically on startup (auto_migrate: true).
Migrations run automatically when:
- The proxy starts with
auto_migrate: true(default) - New tables or columns are detected
To run migrations manually:
# Check current revision
./.venv/Scripts/python.exe -m alembic current
# Run all pending migrations
./.venv/Scripts/python.exe -m alembic upgrade head
# Rollback one migration
./.venv/Scripts/python.exe -m alembic downgrade -1
# Show migration history
./.venv/Scripts/python.exe -m alembic historyFor production environments where you want to control migrations:
database:
auto_migrate: falseThen run migrations as part of your deployment process:
./.venv/Scripts/python.exe -m alembic upgrade headNever commit credentials to version control:
# BAD - credentials in config file
database:
url: "postgresql+asyncpg://user:actual_password@host/db"Use environment variables:
# GOOD - reference environment variable
database:
url: "${DATABASE_URL}"export DATABASE_URL="postgresql+asyncpg://user:password@host/db"For SQLite databases, ensure proper file permissions:
# Restrict access to database file
chmod 600 var/db/proxy.db
# Ensure var/db directory exists with proper permissions
mkdir -p var/db
chmod 700 var/dbFor production PostgreSQL, always use SSL:
database:
url: "postgresql+asyncpg://user:pass@host:5432/db?ssl=require"# Simple file copy (stop proxy first for consistency)
cp var/db/proxy.db var/db/proxy.db.backup
# Or use SQLite backup command
sqlite3 var/db/proxy.db ".backup var/db/proxy.db.backup"# Full database dump
pg_dump -h localhost -U llm_proxy_user llm_proxy > backup.sql
# Restore
psql -h localhost -U llm_proxy_user llm_proxy < backup.sqlSQLite "database is locked":
This usually indicates multiple writers. Ensure only one proxy instance writes to the SQLite database at a time.
PostgreSQL connection refused:
- Verify PostgreSQL is running
- Check host, port, and credentials
- Ensure firewall allows connections
- Check
pg_hba.conffor client authentication
"Target database is not up to date":
Run migrations manually:
./.venv/Scripts/python.exe -m alembic upgrade head"Can't locate revision":
The migration history may be corrupted. Check alembic_version table:
SELECT * FROM alembic_version;Slow queries:
Enable SQL logging to diagnose:
database:
echo: trueConnection pool exhaustion:
Increase pool size for high-traffic deployments:
database:
pool_size: 20
max_overflow: 40- Configuration Guide - Full configuration reference
- ProxyMem Memory - Cross-session memory feature
- SSO Authentication - SSO and token storage
- CLI Parameters - Complete CLI reference