What Information Is Stored in the FreeLLMAPI SQLite Database?
FreeLLMAPI stores its entire runtime state—including model catalogs, encrypted API keys, request logs, rate limits, and user sessions—in a single SQLite file located at data/freeapi.db.
The FreeLLMAPI SQLite database serves as the central persistence layer for this open-source LLM proxy and aggregation service. According to the source code in tashfeenahmed/freellmapi, the schema is initialized via server/src/db/migrations.ts and provides transactional storage for everything from provider credentials to real-time request routing decisions.
Database Location and Initialization
All data resides in a single file on disk. When the server starts, initDb() (defined in server/src/db/index.ts) creates the database at data/freeapi.db and executes the migration script to ensure tables exist.
// Initialise the DB (called once at server start)
import { initDb } from './db/index.js';
initDb(); // creates data/freeapi.db and runs migrations
This monolithic approach simplifies backups and allows the service to run without external database dependencies.
Core Data Tables
Model Catalog and Metadata
The models table stores the complete catalog of every LLM known to the system. Each row records the platform (e.g., OpenAI, Anthropic), model ID, human-readable name, intelligence rankings, speed ratings, size labels, token budgets, and context window limits. This enables the router to make intelligent decisions about which model to invoke based on capability flags.
Secure API Key Storage
User-provided provider credentials live in the api_keys table. Rather than storing plaintext, FreeLLMAPI encrypts keys at rest using AES-256-GCM. The table stores the encrypted key, initialization vector (IV), authentication tag, platform identifier, optional custom base URL, and status flags. The encryption key itself is retrieved from the settings table via getSetting('encryption_key') as implemented in server/src/lib/crypto.ts.
Request Logging and Analytics
Every inbound request is persisted to the requests table for auditing and debugging. This includes the requested platform, model ID, key ID used, response status, input/output token counts, latency metrics, time-to-first-byte (TTFB), and error messages. The logging middleware in the server uses prepared statements to insert these records:
// Insert a new request log (used by the request‑logging middleware)
import { getDb } from './db/index.js';
const db = getDb();
db.prepare(`
INSERT INTO requests
(platform, model_id, key_id, status, input_tokens, output_tokens, latency_ms, error, ttfb_ms, requested_model)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(platform,functions modelId, keyId, status, inTokens, outTokens, latency, err, ttfb, requestedModel);
Rate Limiting and Quota Management
Real-Time Usage Tracking
The rate_limit_usage table maintains per-key, per-model counters that track token consumption for different limit types (RPM, TPM, etc.). This allows the rate limiter—implemented in server/src/services/ratelimit.ts—to enforce throttling in real time without external cache services.
Cooldown and Quota State
When a key exceeds its limits, the rate_limit_cooldowns table records temporary blocks with expiration timestamps. Additionally, provider_quota_state tracks current quota usage per provider/key with reset timestamps, while provider_quota_observations stores historical snapshots that enable predictive limit calculations.
Routing and Fallback Configuration
The fallback_config table contains model-specific priority lists that guide the router when primary models fail. Each entry maps a model database ID to a priority level and enabled flag, instructing the system which alternative to attempt next. The router code in server/src/services/router.ts queries this table alongside models and api_keys to determine forwarding logic.
User Management and Authentication
Authentication data is split across two tables:
users: Stores email addresses and salted password hashes for local authentication.sessions: Contains session tokens tied to user IDs with expiration timestamps, enabling persistent login state.
Organizational Features
Profiles and Collections
Users can organize models into custom collections using the profiles and profile_models tables. The profiles table stores collection metadata including name, emoji, color, type, layout configuration, and auto-sort preferences. The junction table profile_models links profiles to specific models with priority ordering and enabled flags.
Global Settings
The settings table functions as a simple key-value store for global configuration. Critical values include the unified_api_key used by desktop clients, the encryption_key for database encryption, default embedding families, and the active profile ID. Access these via typed helpers in server/src/db/index.ts:
// Read a setting (e.g., the unified API key)
import { getSetting } from './db/index.js';
const unifiedKey = getSetting('unified_api_key');
Specialized Model Metadata
The database tracks specialized capabilities beyond standard chat models:
embedding_models: Metadata for models supporting vector embeddings, including token limits and display names.media_models: Information about multimodal models, including supported modalities, priority rankings, and quota labels.quirksandquirk_targets: Document known provider-specific behaviors (stored inquirks) and map them to affected platforms or model glob patterns viaquirk_targets.model_pricing(optional): Defined inserver/src/db/model-pricing.ts, this table stores per-token pricing data used for cost estimation and budgeting.
Accessing the Database Programmatically
The codebase provides helper functions in server/src/db/index.ts to interact with the SQLite store safely. To fetch enabled models for a specific platform:
// Fetch all enabled models for a given platform (used by the router)
import { getDb } from './db/index.js';
const rows = getDb()
.prepare('SELECT * FROM models WHERE platform = ? AND enabled = 1')
.all('openai');
These utilities wrap the better-sqlite3 driver and handle connection pooling automatically.
Summary
- FreeLLMAPI uses a single SQLite file (
data/freeapi.db) for all persistence, initialized byserver/src/db/migrations.ts. - Encrypted credentials are stored in the
api_keystable using AES-256-GCM encryption. - Complete request history is logged to the
requeststable with latency and token metrics. - Rate limiting relies on
rate_limit_usageandrate_limit_cooldownsfor real-time enforcement. - Routing logic uses
fallback_configandmodelsto determine provider selection. - User data is managed via
usersandsessionstables with salted hashes. - Organizational features include the
profilesandprofile_modelstables for custom model collections. - Specialized metadata covers embeddings, media capabilities, provider quirks, and optional pricing data.
Frequently Asked Questions
Where is the FreeLLMAPI SQLite database file located?
The database is created at data/freeapi.db relative to the server root when initDb() is first called. This path is hardcoded in the migration system and requires no external database configuration.
How are API keys secured in the FreeLLMAPI database?
API keys are encrypted at rest using AES-256-GCM. The api_keys table stores the ciphertext along with the initialization vector and authentication tag. The encryption key is retrieved from the settings table and managed via server/src/lib/crypto.ts.
What request metrics does FreeLLMAPI store for analytics?
The requests table captures platform, model ID, key ID, HTTP status, input/output token counts, total latency in milliseconds, time-to-first-byte (TTFB), error messages, and the originally requested model name. This data enables detailed usage analytics and debugging.
Does FreeLLMAPI support organizing models into custom groups?
Yes. The profiles table allows users to create named collections with custom emojis, colors, and layouts. The profile_models junction table links these profiles to specific models with configurable priority ordering, enabling quick switching between different model configurations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →