SQLite Storage
Libre WebUI stores application data in SQLite by default. The storage layer keeps chats, messages, users, preferences, documents, document chunks, personas, plugin credentials, memories, and related metadata in one local database.
Database Location
The backend uses this location order:
DATA_DIRwhen set.backend/datafrom the project root.
The SQLite file is named data.sqlite.
Example:
DATA_DIR=/var/lib/libre-webui
What SQLite Stores
- Users and roles
- Sessions and messages
- Preferences and UI settings
- Documents and chunks
- Personas and persona settings
- Persona memories and mutation state
- Plugin credentials and their routing/auth bindings, variables, per-user activations, writable-definition approvals, and discovered model catalogs
- System settings
- Work task ownership, model/provider routing, runs, messages, tool activity, status, and Docker resource identifiers
Sensitive values are encrypted at the application layer when they pass through the encrypted storage helpers.
Work Storage Is Split
Work conversation and task metadata live in SQLite, but Work files do not. Each
task receives a dedicated Docker named volume mounted at /workspace. The
container is replaceable execution state; the named volume is the task's durable
filesystem.
This means a database backup by itself is not a complete Work backup. Back up
the corresponding Docker volumes using your Docker host's volume-backup process.
Libre WebUI labels managed Work volumes with
ai.libre-webui.managed=true and the owning task ID.
Deleting a Work task permanently removes its SQLite records and managed named volume. Cancelling a run, stopping a preview, or restarting the backend does not delete its files.
JSON Compatibility
Older Libre WebUI installs used JSON files for some data. Current builds use SQLite as the primary storage path and keep storage access behind service/model layers so the rest of the app does not need to know the persistence format.
If you are upgrading an old install, back up the whole data directory before starting the newer backend.
Legacy plugin activation in .status.json is migrated once into per-user
SQLite rows for accounts that exist at upgrade time, but only for exact
hash-anchored bundled definitions. Legacy custom and shadow definitions remain
quarantined until an administrator re-imports them, and approval does not
restore old activation rows. Later accounts start with no active plugins, and
each account's activation changes are independent.
Backup
Stop the backend before copying the database:
cp -R backend/data backend/data.backup
For deployments using DATA_DIR:
cp -R "$DATA_DIR" "$DATA_DIR.backup"
If the instance uses Work, also back up every managed Work named volume while the backend is stopped. Keep the database, encryption key, and Work-volume backup from the same point in time.
Restore
Stop the backend, replace the data directory with your backup, then restart. Keep the same ENCRYPTION_KEY; encrypted values cannot be decrypted with a different key.
For Work, restore the named volumes under the exact names recorded in the restored database before starting the backend. Libre WebUI can recreate a task container, but it cannot reconstruct missing workspace files from the conversation history.
Operational Notes
- SQLite runs with WAL enabled for better concurrent reads.
- The data directory must be writable by the backend process.
- Keep
DATA_DIRon persistent storage in Docker and Kubernetes. - Back up
ENCRYPTION_KEYtogether with the database. - Account for Work named volumes separately when measuring, migrating, or restoring storage.