Database Selection Guide
This guide helps you choose between SQLite and PostgreSQL for your LLM Proxy deployment.
Overview
The LLM Proxy supports two database backends:
| Feature | SQLite | PostgreSQL |
|---|---|---|
| Setup Complexity | Zero configuration | Requires server setup |
| Scalability | Single instance | Multiple instances |
| Concurrent Writes | Limited | Excellent |
| Best For | Development, small deployments | Production, high-traffic |
| Maintenance | None | Requires DBA knowledge |
SQLite (Default)
SQLite is the default database, requiring no additional setup.
When to Use SQLite
- Development and testing - Zero configuration, runs anywhere
- Single-instance deployments - Up to moderate traffic
- Edge deployments - Minimal resource requirements
- Prototyping - Quick start without external dependencies
Configuration
# SQLite is the default - no additional configuration needed
export DB_DRIVER=sqlite
export DATABASE_PATH=./data/llm-proxy.db
Performance Characteristics
- Read performance: Excellent for moderate concurrent reads
- Write performance: Single-writer model, limited concurrent writes
- Recommended limit: ~100 requests/second per instance
Limitations
- Cannot scale horizontally (single instance only)
- Write contention under heavy load
- Not suitable for distributed deployments
PostgreSQL
PostgreSQL is recommended for production deployments with higher traffic or multiple instances.
When to Use PostgreSQL
- Production deployments - Better reliability and monitoring
- High traffic - Handles thousands of concurrent connections
- Multiple instances - Required for horizontal scaling
- Advanced features - Full-text search, JSON queries, etc.
Configuration
export DB_DRIVER=postgres
export DATABASE_URL=postgres://user:password@localhost:5432/llmproxy?sslmode=require
# Optional: Connection pool settings
export DATABASE_POOL_SIZE=10
export DATABASE_MAX_IDLE_CONNS=5
export DATABASE_CONN_MAX_LIFETIME=1h
Connection String Format
postgres://[user]:[password]@[host]:[port]/[database]?sslmode=[mode]
SSL Mode Options:
| Mode | Description | Use Case |
|---|---|---|
disable |
No SSL | Development only |
require |
SSL required, no verification | Cloud databases |
verify-ca |
SSL with CA verification | High security |
verify-full |
Full certificate verification | Maximum security |
Examples:
# Local development (no SSL)
DATABASE_URL=postgres://llmproxy:secret@localhost:5432/llmproxy?sslmode=disable
# AWS RDS
DATABASE_URL=postgres://user:pass@mydb.xxx.rds.amazonaws.com:5432/llmproxy?sslmode=require
# Google Cloud SQL
DATABASE_URL=postgres://user:pass@/llmproxy?host=/cloudsql/project:region:instance
# Azure PostgreSQL
DATABASE_URL=postgres://user@server:pass@server.postgres.database.azure.com:5432/llmproxy?sslmode=require
Performance Characteristics
- Read performance: Excellent with proper indexing
- Write performance: Excellent with connection pooling
- Concurrent connections: Thousands with proper configuration
- Recommended: 100+ requests/second, multiple instances
Migration Between Databases
SQLite to PostgreSQL
-
Export data from SQLite:
sqlite3 data/llm-proxy.db ".dump projects" > projects.sql sqlite3 data/llm-proxy.db ".dump tokens" > tokens.sql -
Start PostgreSQL:
docker compose --profile postgres up -d postgres -
Update configuration:
export DB_DRIVER=postgres export DATABASE_URL=postgres://llmproxy:secret@localhost:5432/llmproxy?sslmode=disable -
Start the proxy (migrations run automatically):
llm-proxy server -
Import data (requires SQL syntax adaptation):
# Note: SQLite and PostgreSQL SQL dialects differ # Manual adjustment of exported SQL may be required
Considerations
- Schema migrations: Run automatically on startup for both databases
- Data migration: Manual process, requires SQL dialect conversion
- Downtime: Plan for maintenance window during migration
Connection Pooling
Both databases support connection pooling to optimize performance.
SQLite Pool Settings
SQLite uses a single-connection pool internally due to its single-writer architecture:
# SQLite automatically uses MaxOpenConns=1 for :memory: databases
# For file-based databases, pooling is configurable but limited
export DATABASE_POOL_SIZE=10
PostgreSQL Pool Settings
PostgreSQL benefits significantly from connection pooling:
# Production settings
export DATABASE_POOL_SIZE=20
export DATABASE_MAX_IDLE_CONNS=10
export DATABASE_CONN_MAX_LIFETIME=30m
Sizing Guidelines:
| Deployment Size | Pool Size | Idle Conns | Max Lifetime |
|---|---|---|---|
| Small (<100 rps) | 10 | 5 | 1h |
| Medium (100-500 rps) | 20 | 10 | 30m |
| Large (500+ rps) | 50+ | 20 | 15m |
Monitoring
SQLite Monitoring
SQLite statistics are available via the metrics endpoint:
curl http://localhost:8080/metrics | grep database
PostgreSQL Monitoring
PostgreSQL provides additional monitoring capabilities:
-- Connection count
SELECT count(*) FROM pg_stat_activity WHERE datname = 'llmproxy';
-- Table sizes
SELECT relname, pg_size_pretty(pg_total_relation_size(relid))
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;
Troubleshooting
See the PostgreSQL Troubleshooting Guide for common issues and solutions.