Skip to content
Olyx

Database and storage

Set up local SQLite storage, retention, backups, and temporary storage for the CLI.

The CLI uses SQLite for traces. SQLite is bundled into the binary: you do not need to install a database server, create tables, or run migrations. The CLI creates its database and schema automatically when you run route, replay, debug, or serve.

Omit database to use data/traces.db beside the configuration file. Storage and retention settings are optional.

Option Configuration Behavior
Persistent SQLite file "database": "../data/traces.db" Keeps traces between commands and restarts
Temporary in-memory SQLite "database": ":memory:" Loses all data when the command exits

Use a persistent file for debugging and replay. PostgreSQL, MySQL, object-storage backends are not supported by the CLI.

In your CLI configuration, set database to a file path. The repository’s examples/olyx.json already uses ../data/traces.db:

Update these storage fields in your complete configuration, keeping its existing model aliases:

{
"database": "../data/traces.db",
"policy": {
"retention_days": 30
}
}

You can also use an absolute path, such as /var/lib/olyx/traces.db. On Windows, escape backslashes in JSON, for example "C:\\Users\\you\\olyx\\traces.db". Use a concrete path: shell shortcuts such as ~ and $HOME are not expanded inside the JSON file.

From the CLI repository directory:

Terminal window
export OPENAI_API_KEY=your-provider-key
olyx check examples/olyx.json
olyx route --config examples/olyx.json --input examples/request.json
olyx debug --config examples/olyx.json

check validates configuration but does not create the database or test directory permissions. The first local runtime command creates missing parent directories and opens the database. Its directory must be writable by the user running the CLI.

The database stores trace metadata, recorded model requests and responses, attempted models, failures, and latency.

SQLite uses write-ahead logging with full synchronous commits. You may see traces.db-wal and traces.db-shm beside the database. Keep these files on the same local filesystem as the database; do not remove them while commands are running. Prefer local disk over a network share or a directory managed by a file-sync application.

On Unix, newly created storage directories are owner-only (0700); database and journal files are owner-only (0600). Existing directories retain their existing permissions. On Windows, use a directory restricted to your user account. File permissions protect access; the CLI does not encrypt the database.

If Olyx stops before a request finishes, the next command that opens the same database checks whether the process that owned the trace is still running. Abandoned traces become failed with the diagnostic code request_interrupted. Requests still owned by an active CLI process remain pending.

Terminal window
olyx debug --config olyx.json
olyx debug TRACE_ID --config olyx.json

Replace TRACE_ID with the interrupted trace’s ID. Saved provider attempts remain available. Recovery does not resend requests: a provider may already have processed the original request and incurred usage. Inspect the trace before retrying.

Pending traces written by older versions without ownership records are left unchanged because Olyx cannot safely determine whether their requests are active. Corrupt stored JSON raises a storage error rather than being returned as null.

Set policy.retention_days to a positive integer. The default is 30 days.

{
"policy": {
"retention_days": 90
}
}

Merge this setting into your complete configuration. Expired traces and their steps are deleted when a local runtime command opens the database. There is no background cleanup process. Expired traces cannot be replayed. Shortening retention takes effect the next time you run a local runtime command.

Use SQLite’s backup facility for a consistent copy that includes committed data in the WAL. If you have the optional sqlite3 command installed, run this from the repository directory:

Terminal window
mkdir -p backups
sqlite3 data/traces.db ".backup 'backups/traces.db'"

The sqlite3 command is a backup utility; it is not required to run Olyx. Another option, if Python 3 is installed, is its standard-library SQLite backup API:

from pathlib import Path
import sqlite3
Path("backups").mkdir(exist_ok=True)
with sqlite3.connect("file:data/traces.db?mode=ro", uri=True) as source:
with sqlite3.connect("backups/traces.db") as destination:
source.backup(destination)

Backups contain recorded payloads, so store them with appropriate access permissions. To use a backup, stop any commands using it, make a working copy, and set database in a configuration file to that copy’s path. Opening the copy also applies the configuration’s retention policy.

{
"database": ":memory:"
}

Replace only database in an otherwise complete configuration. This is useful for a throwaway routing run. Each CLI invocation starts a new database, so a later debug or replay command cannot find traces from an earlier invocation. Use a persistent file to keep traces across commands.

Symptom What to check
Cannot open database Check the resolved path and parent-directory permissions
Trace not found Use the same configuration/database as the original route; check retention and avoid :memory:
request_interrupted The owning process ended; inspect saved attempts before explicitly retrying
Database is locked Let the other writer finish; the CLI waits up to five seconds for SQLite locks

Continue with the quickstart or Olyx CLI overview.