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:
node:sqlite– Node.js 22.5+ built-in SQLite module (preferred fallback)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-sqlite3native driver - WAL journaling enables safe concurrent reads and writes with automatic crash recovery
- Configuration uses
DATA_DIRfor storage location andSTORAGE_DRIVER(fixed tosqlite) - Runtime fallbacks to
node:sqlite(Node 22.5+) andsql-jsexist for unsupported platforms - The
getDbInstance()singleton insrc/lib/db/core.tsmanages 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →