# What Database Does FreeLLMAPI Use for Persistence?

> Discover why FreeLLMAPI uses an embedded SQLite database for persistence. Learn how it stores rate-limit counters, key status, and request analytics efficiently.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: internals
- Published: 2026-06-26

---

**FreeLLMAPI persists application state in an embedded SQLite database, using the `better-sqlite3` Node.js driver to store rate-limit counters, provider key status, and request analytics on disk.**

FreeLLMAPI is an open-source unified API gateway for large language models. Unlike traditional deployments requiring external database servers, the project uses a lightweight, serverless **SQLite** database for all persistence needs, ensuring simple deployment without additional infrastructure dependencies.

## SQLite Architecture and Implementation

The application leverages SQLite as its sole persistence layer, eliminating the complexity of managing separate database processes. This embedded approach aligns with the project's goal of minimal configuration while maintaining reliable storage for critical runtime data.

### Database Initialization in [`server/src/db/index.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/db/index.ts)

The database connection layer resides in [[`server/src/db/index.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/db/index.ts)](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/db/index.ts), where the application initializes the SQLite connection and executes schema migrations on startup. This module configures the `better-sqlite3` instance with Write-Ahead Logging (WAL) mode enabled, allowing concurrent read performance while maintaining ACID compliance for write operations.

### File Location and Docker Persistence

When running locally, the database file `freellmapi.db` is created in the `server/data/` directory relative to the project root. In production Docker deployments, this file is stored in a named volume `freellmapi-data` mounted at `/app/server/data` inside the container [source](https://github.com/tashfeenahmed/freellmapi/blob/main/README.md#L1005). This volume configuration ensures that rate-limit counters and analytics data survive container restarts and can be backed up by copying a single file from the host volume.

## Data Persistence Scope

FreeLLMAPI stores several critical data structures in SQLite:

- **Rate-limit counters**: Tracked in [[`server/src/services/ratelimit.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/ratelimit.ts)](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/ratelimit.ts) and persisted to disk to maintain accurate quotas across server restarts
- **Provider key metadata**: Encrypted API key status, rotation history, and provider configuration
- **Request analytics**: Detailed logs of model usage, endpoint latency, token consumption, and error rates

## Querying the SQLite Database Directly

Developers can inspect the database using standard SQLite tools or programmatically via the `better-sqlite3` driver.

**Local file path resolution:**

```typescript
import path from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const dbPath = path.join(process.cwd(), "server", "data", "freellmapi.db");

console.log("SQLite database location:", dbPath);

```

**Direct SQL queries using better-sqlite3:**

```typescript
import Database from "better-sqlite3";

// Use the Docker path when running in containers
const db = new Database("/app/server/data/freellmapi.db");

const rows = db.prepare(`
  SELECT id, model, endpoint, created_at 
  FROM request_logs 
  ORDER BY created_at DESC 
  LIMIT 10
`).all();

console.table(rows);
db.close();

```

**Inspecting rate limits via the REST API:**

```bash
curl http://localhost:3001/api/ratelimit \
  -H "Authorization: Bearer freellmapi-your-unified-key"

```

## Docker Volume Configuration

The [[`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml)](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) defines a persistent named volume that maps host storage to the container's database directory. This volume mount at `/app/server/data` ensures that the `freellmapi.db` file persists independently of the container lifecycle, supporting production deployments without external database servers [source](https://github.com/tashfeenahmed/freellmapi/blob/main/README.md#L2066).

## Summary

- FreeLLMAPI uses **SQLite** as its sole persistence layer, accessed via the synchronous `better-sqlite3` package.
- The database file `freellmapi.db` is stored in `server/data/` locally or `/app/server/data` in Docker containers.
- **Rate-limit counters**, provider key metadata, and request analytics are all written to this embedded database.
- Docker deployments utilize a named volume `freellmapi-data` to ensure data survives container restarts and enables simple file-based backups.

## Frequently Asked Questions

### Does FreeLLMAPI require PostgreSQL or MySQL for production?

No. FreeLLMAPI is architected to run entirely with SQLite, eliminating the need for external database servers. The `better-sqlite3` driver provides sufficient performance for the API gateway's rate-limiting and analytics workloads, making deployments simpler and reducing infrastructure overhead.

### Where is the database file located in a Docker deployment?

In Docker environments, the SQLite database is stored at `/app/server/data/freellmapi.db` inside the container, mapped to a named volume called `freellmapi-data` on the host. This path is configured in the Docker Compose volume mounts and ensures your data persists even when containers are destroyed and recreated.

### How can I back up the FreeLLMAPI database?

Since SQLite stores data in a single file, backups are straightforward. Copy the `freellmapi.db` file from the `server/data/` directory (or the Docker volume mount point) to your backup location. You can also use the `.backup` command in the SQLite CLI or standard file system snapshots, as the database supports hot backups while the application is running.

### Which Node.js package handles database connections?

The application uses **`better-sqlite3`** to manage SQLite connections. This synchronous, high-performance driver is initialized in [`server/src/db/index.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/db/index.ts) and provides methods for prepared statements, transactions, and schema migrations required by the rate-limiting and analytics services.