Skip to main content

SQLite

SQLite is the default state driver. AlmaForge uses it when no state StorageConfig resource is supplied, or when spec.sqlite is set explicitly. The database is sqlite.db inside the configured directory. There is no database server to provision. An explicit StorageConfig must select exactly one driver.

Storage concernSupported
Cluster state (name: state)yes
Audit events (name: audit-*)no
Session recordings (name: recordings)no

TL;DR​

  1. Keep the default database directory or choose another local path (Step 1).
  2. Write a StorageConfig resource with spec.sqlite (Step 2).
  3. Restart the Auth Service and verify with alma get storageconfig (Step 3).

Prerequisites​

Before you start, make sure you have:

  • A single Auth Service host. SQLite is not a shared backend, so do not use it for an HA pool. See PostgreSQL or DynamoDB if you need HA.
  • Write access to the data directory on the Auth host (/var/lib/almaforge by default). The directory is created with mode 0700 and the database file with mode 0600 on first start.
  • A local block device for /var/lib/almaforge. Keep SQLite state off NFS, SMB, and other shared network filesystems.
  • Permission to edit the bootstrap file on the Auth host and restart almad.

Configuration​

Step 1. Pick a database path​

The default directory is /var/lib/almaforge/backend, containing sqlite.db. Keep it unless you need another local disk. spec.sqlite.path names the directory, not the database file.

If you keep the default, there is nothing else to do in Step 1. almad creates the directory and the database file on first start.

For a custom path, create the parent directory first. almad runs as root, so make the directory root-owned and readable only by root:

Terminal
sudo mkdir -p /var/local/almaforgesudo chown root:root /var/local/almaforgesudo chmod 0700 /var/local/almaforge

Step 2. Write the StorageConfig resource​

Place this in the Auth Service bootstrap file:

state.yaml:

examples/storage/sqlite/state.yaml
# Explicit SQLite cluster-state backend at the default path.
apiVersion: almaforge.com/v1
kind: StorageConfig
metadata:
name: state
spec:
sqlite:
path: /var/lib/almaforge/backend

If you are running with the default path, you can also omit the entire StorageConfig resource. AlmaForge falls back to SQLite at /var/lib/almaforge/backend automatically.

For a single-node dev cluster that needs higher write throughput, trade durability for speed by enabling WAL mode and relaxing fsync:

performance.yaml:

examples/storage/sqlite/performance.yaml
# SQLite settings for higher dev throughput with weaker power-loss durability.
apiVersion: almaforge.com/v1
kind: StorageConfig
metadata:
name: state
spec:
sqlite:
path: /var/lib/almaforge/backend
sync: NORMAL
journal: WAL
busyTimeout: 15000

The performance fields match the SQLite PRAGMA names. See Performance tuning under Operations for the trade-offs.

Step 3. Restart and verify​

Restart the Auth Service to pick up the bootstrap file:

Terminal
sudo systemctl restart almad

Verify the resource is loaded:

Terminal
alma get storageconfig/state -o yaml

The output should echo back the same spec.sqlite block you wrote, with any defaults filled in. If you used the default path with no explicit StorageConfig, the output shows spec.sqlite.path: /var/lib/almaforge/backend.

The integration is working when alma get storageconfig/state returns successfully and sqlite.db exists inside the configured directory.

URI form​

Equivalent URI string, suitable for an environment variable or a CLI flag:

text
sqlite:///var/lib/almaforge/backend?buffer_size=1024&poll_stream_period=1s&sync=FULL&busy_timeout=10000&journal=delete

Canonical query keys are snake_case (buffer_size, poll_stream_period, sync, busy_timeout, journal). The typed JSON-tag form (bufferSize, etc.) is accepted as an alias. Empty keys keep the built-in defaults.

Troubleshooting​

database is locked​

Check for another almad process or database tool holding a write lock. Run only one Auth Service against this backend and stop any duplicate process. A lock error alone does not establish data corruption. If errors continue with one Auth process, preserve the database directory and follow backup and recovery guidance.

SLOW TRANSACTION warnings in the Auth log​

A transaction took longer than one second. Check disk latency, host load, and competing writers before changing backend. If sustained write latency affects login flows, plan capacity for a shared backend such as PostgreSQL, DynamoDB, or etcd. See Performance tuning for the available settings.

unable to open database file​

The Auth Service cannot create or open sqlite.db inside spec.sqlite.path. Check that the filesystem is mounted, has free space, and allows root to create and write the database directory.

Database file lives on NFS or another networked filesystem​

Move SQLite state to a local block device using the backup and restore procedure. Network filesystem locking and consistency are not a substitute for a shared state driver. Use PostgreSQL or etcd for shared Auth state.

Operations​

Backup and restore​

Stop almad, back up the entire directory at spec.sqlite.path, and restart it. Copying the directory preserves sqlite.db and any journal or WAL files together. Keep the bootstrap files and secrets needed to restore the host as well. Follow the Backups guide for the complete recovery procedure and verify a restore before relying on the backup.

An atomic filesystem snapshot must capture the database and its journal files together. For an online database backup, SQLite's .backup command uses the Online Backup API, which permits other connections to keep using the database. Check that the backup completes successfully, and preserve the separate host configuration and secrets as well.

Performance tuning​

The three SQLite PRAGMA fields trade durability for throughput:

  • sync: NORMAL skips the per-transaction fsync. Crash recovery is still correct but a sudden power loss can lose the last few committed transactions.
  • sync: OFF disables fsync entirely. Only acceptable if you can rebuild the cluster after a power loss.
  • journal: WAL switches to Write-Ahead Logging for significantly higher concurrent throughput. Requires a local filesystem with proper file locks.
  • busyTimeout (milliseconds, default 10000) controls how long SQLite waits on a busy lock before erroring. Increasing it allows a longer wait. It does not make transactions faster.

These knobs buy time, not capacity. A cluster that has outgrown SQLite needs an HA driver.

High availability​

SQLite supports a single Auth Service, not an HA pool. Separate local files create separate state stores, and sharing one SQLite directory between Auth instances is unsupported. Plan a cutover to a shared driver before adding another Auth host.

Configuration changes​

StorageConfig is bootstrap-only. To change the SQLite path or any tuning field, edit the bootstrap file and restart almad. See storage configuration changes.

Removal​

Changing the driver does not migrate the existing cluster state. Plan the cutover before changing StorageConfig, take a final backup of the SQLite directory, and retain it until the replacement is verified. Starting against an empty backend creates fresh cluster state. See Backups for recovery coverage and Support before a cross-driver migration that must preserve an existing cluster.

References​