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 concern | Supported |
|---|---|
Cluster state (name: state) | yes |
Audit events (name: audit-*) | no |
Session recordings (name: recordings) | no |
TL;DR
- Keep the default database directory or choose another local path (Step 1).
- Write a
StorageConfigresource withspec.sqlite(Step 2). - 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/almaforgeby default). The directory is created with mode0700and the database file with mode0600on 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:
sudo mkdir -p /var/local/almaforgesudo chown root:root /var/local/almaforgesudo chmod 0700 /var/local/almaforgeStep 2. Write the StorageConfig resource
Place this in the Auth Service bootstrap file:
# 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:
# 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:
sudo systemctl restart almadVerify the resource is loaded:
alma get storageconfig/state -o yamlThe 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:
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: NORMALskips the per-transaction fsync. Crash recovery is still correct but a sudden power loss can lose the last few committed transactions.sync: OFFdisables fsync entirely. Only acceptable if you can rebuild the cluster after a power loss.journal: WALswitches to Write-Ahead Logging for significantly higher concurrent throughput. Requires a local filesystem with proper file locks.busyTimeout(milliseconds, default10000) 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
- Storage backends overview.
- High availability.
- PostgreSQL driver. The usual migration target when a SQLite cluster outgrows a single node.
- SQLite PRAGMA reference. Upstream documentation for
synchronous,journal_mode, andbusy_timeout.