What Database Does OmniRoute Use and How Is It Configured?

OmniRoute uses SQLite via the better-sqlite3 driver with WAL journaling enabled, configured through environment variables like DATA_DIR for storage location.

OmniRoute persists all state—including providers, models, routing combos, API keys, and usage logs—in a single SQLite database. The architecture prioritizes simplicity, reliability, and concurrent access safety through write-ahead logging. Configuration is environment-driven with sensible defaults, making deployment straightforward across local development and containerized production environments.

Core Database Technology: SQLite with better-sqlite3

OmniRoute relies on SQLite as its sole persistence layer. The native Node addon better-sqlite3 provides synchronous, high-performance access to the database, avoiding the complexity of external database servers.

The database is instantiated as a singleton via getDbInstance() in [src/lib/db/core.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/src/lib/db/core.ts). This ensures a single connection is reused throughout the application lifecycle, preventing file locking issues and connection pool overhead.

WAL Mode for Concurrent Access

When the database opens, OmniRoute automatically enables write-ahead-log (WAL) journaling with PRAGMA journal_mode=WAL. This configuration delivers two critical benefits:

  • Concurrent reads and writes – Multiple processes can query the database while a single write proceeds through the WAL
  • Crash recovery – The WAL allows fast, automatic recovery without requiring full database verification

The resulting file layout follows standard SQLite conventions:


${DATA_DIR}/storage.sqlite          # main database file

${DATA_DIR}/storage.sqlite-wal      # write-ahead log

${DATA_DIR}/storage.sqlite-shm      # shared-memory index

Environment-Based Configuration

OmniRoute database configuration is controlled through environment variables defined in [docs/reference/ENVIRONMENT.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/reference/ENVIRONMENT.md) and [docs/ops/DATABASE_GUIDE.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/ops/DATABASE_GUIDE.md):

Variable Purpose Default
DATA_DIR Directory containing storage.sqlite ~/.omniroute (local) or /app/data (Docker)
STORAGE_DRIVER Database driver selection sqlite (fixed, no runtime alternatives)
OMNIROUTE_SKIP_POSTINSTALL Skip native dependency rebuild 0 (set to 1 for CI environments)
OMNIROUTE_BUILDING Build-phase detection Undefined (sets DB to no-op stub when present)

Changing the Storage Location

Relocate the database by overriding DATA_DIR:


# Local development

export DATA_DIR=/var/lib/omniroute
omniroute start

# Docker deployment

docker run -v /host/data:/app/data -e DATA_DIR=/app/data diegosouzapw/omniroute

Build-Time Database Handling

During build processes, setting OMNIROUTE_BUILDING prevents the native addon from loading. The [src/lib/buildPhase.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/src/lib/buildPhase.ts) module returns a no-op stub, allowing Next.js builds and other compilation steps to proceed without database initialization.

Runtime Fallback Resolver

If the bundled better-sqlite3 binary fails to load—due to platform incompatibility or missing native dependencies—OmniRoute activates a runtime resolver at bin/cli/runtime/sqliteRuntime.mjs. This resolver attempts two pure-JavaScript alternatives in order:

  1. node:sqlite – Node.js 22.5+ built-in SQLite module (preferred fallback)
  2. sql-js – In-memory SQLite implementation (last-resort fallback)

These alternatives are documented in [docs/ops/SQLITE_RUNTIME.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/ops/SQLITE_RUNTIME.md). Performance degrades progressively: better-sqlite3 offers native speed, node:sqlite provides acceptable throughput for moderate loads, and sql-js should only be used for development or minimal deployments.

Working with the Database in Code

Obtaining the Database Instance

Import the singleton from the core module:

import { getDbInstance } from '@/src/lib/db/core';

// Returns the singleton better-sqlite3 Database object
const db = getDbInstance();

Executing Queries

Prepared statements provide optimal performance and SQL injection protection:

// Read operation with parameter binding
const rows = db.prepare(`
  SELECT id, name, api_key
  FROM providers
  ORDER BY id
  LIMIT 5
`).all();

console.log(rows);

Transactional Writes

The WAL-enabled database supports atomic transactions with automatic rollback:

const insert = db.prepare(`
  INSERT INTO api_keys (key, owner, created_at)
  VALUES (?, ?, datetime('now'))
`);

// Transaction rolls back on any thrown error
db.transaction(() => {
  insert.run('my-secret-key', 'admin');
  insert.run('secondary-key', 'service-account');
})();

Operational Maintenance

Integrity Verification

Validate database health using the standard SQLite CLI:

sqlite3 $DATA_DIR/storage.sqlite "PRAGMA integrity_check;"

Expected output: ok

Backup and Recovery

Since SQLite stores everything in a single file, standard filesystem tools apply:


# Hot backup (safe with WAL mode)

cp $DATA_DIR/storage.sqlite $DATA_DIR/backup-$(date +%Y%m%d).sqlite

# Restore

cp backup-20240115.sqlite $DATA_DIR/storage.sqlite

WAL Checkpointing

Long-running deployments should periodically run PRAGMA wal_checkpoint(TRUNCATE) to prevent unlimited WAL growth. OmniRoute does not auto-checkpoint; schedule this via cron or application hooks for high-write workloads.

Key Source Files

Path Responsibility
[src/lib/db/core.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/src/lib/db/core.ts) Singleton instantiation, WAL configuration, connection utilities
[docs/reference/ENVIRONMENT.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/reference/ENVIRONMENT.md) Environment variable reference
[docs/ops/DATABASE_GUIDE.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/ops/DATABASE_GUIDE.md) OS paths, backup procedures, maintenance
[docs/ops/SQLITE_RUNTIME.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/ops/SQLITE_RUNTIME.md) Fallback driver documentation
bin/cli/runtime/sqliteRuntime.mjs Runtime driver selection logic

Summary

  • SQLite is OmniRoute's sole database, accessed through the better-sqlite3 native driver
  • WAL journaling enables safe concurrent reads and writes with automatic crash recovery
  • Configuration uses DATA_DIR for storage location and STORAGE_DRIVER (fixed to sqlite)
  • Runtime fallbacks to node:sqlite (Node 22.5+) and sql-js exist for unsupported platforms
  • The getDbInstance() singleton in src/lib/db/core.ts manages all database access
  • File-based storage simplifies backup, migration, and container deployment

Frequently Asked Questions

Can OmniRoute use PostgreSQL or MySQL instead of SQLite?

No. According to the source code in [docs/reference/ENVIRONMENT.md](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/docs/reference/ENVIRONMENT.md), STORAGE_DRIVER is fixed to sqlite with no runtime selection mechanism. The entire application assumes SQLite semantics and file-based storage.

How do I run OmniRoute with the database on a network-attached storage?

Set DATA_DIR to a mounted path with proper locks support. However, SQLite over network filesystems (NFS, SMB) risks corruption due to locking limitations. For production, prefer local SSD storage or use a single container with persistent volume claims that guarantee POSIX advisory locks.

What happens if better-sqlite3 fails to install on my platform?

The runtime resolver at bin/cli/runtime/sqliteRuntime.mjs automatically attempts node:sqlite (Node 22.5+) then sql-js. Set OMNIROUTE_SKIP_POSTINSTALL=1 during npm install to bypass native builds in CI, then verify runtime fallback behavior matches your performance requirements.

Is the database encrypted at rest?

No native encryption is configured by default. The encryptConnectionFields helper in [src/lib/db/core.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.51/src/lib/db/core.ts) handles field-level encryption for sensitive connection data, but the database file itself is unencrypted. Use filesystem-level encryption (LUKS, BitLocker, EBS encryption) for compliance requirements.

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 →