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.
  • quirks and quirk_targets: Document known provider-specific behaviors (stored in quirks) and map them to affected platforms or model glob patterns via quirk_targets.
  • model_pricing (optional): Defined in server/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 by server/src/db/migrations.ts.
  • Encrypted credentials are stored in the api_keys table using AES-256-GCM encryption.
  • Complete request history is logged to the requests table with latency and token metrics.
  • Rate limiting relies on rate_limit_usage and rate_limit_cooldowns for real-time enforcement.
  • Routing logic uses fallback_config and models to determine provider selection.
  • User data is managed via users and sessions tables with salted hashes.
  • Organizational features include the profiles and profile_models tables 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →