Skip to content

Storage and retention

Relay defaults to messageStorage: [sqlite, text]: SQLite structured history plus plain-text logs, gated by each account's logging preference. Text logs alone do not provide search, threads from stored history, or Activity. PostgreSQL can replace SQLite as the primary structured backend.

PostgreSQL

Configure config.yaml or use Administration > Storage:

messageStorage:
  - postgres
postgres:
  connectionString: postgres://user:password@host/database
  maxOpenConns: 10
  maxIdleConns: 5
  connMaxLifetimeMinutes: 60

Starting PostgreSQL alone does not switch Relay. Select postgres as the primary backend, supply a valid connection string, and restart Relay. The web UI treats the connection string as write-only.

To copy existing SQLite history after configuring PostgreSQL:

relay storage import-sqlite

Pass a username to migrate one account, or in Docker run docker exec -it relay relay storage import-sqlite. The source SQLite files remain in place; back up all Relay data first. Stop the server while importing and run the command against the same RELAY_HOME; restart afterward and compare history/search for each migrated account. storage migrate applies schema migrations to the configured provider; it does not copy SQLite history into PostgreSQL.

Current master storage configuration

After 0.11.2, master uses one database backend for both history and short links:

storage:
  backend: postgres
  options:
    connectionString: postgres://user:password@host/database?sslmode=require
    maxOpenConns: 10
    maxIdleConns: 5
    connMaxLifetimeMinutes: 60
  messageHistory: true
  textLogs: true

The default backend is SQLite with empty options and both logging switches enabled. Account logging must also be enabled for history. Legacy messageStorage and postgres settings remain readable; do not combine conflicting old and new values in the same configuration layer. Administrator overrides still take precedence. Restart after changing the backend or its options; Relay does not silently switch databases if the configured provider is unavailable.

Before using PostgreSQL with existing shortlinks.sqlite3, stop all Relay instances sharing the data or database, back up, then run relay storage import-shortlinks-sqlite with the destination configuration and the same RELAY_HOME. Use a build containing both database modules. The import preserves the source and skips identical rows; conflicting codes abort the import. Without a completed import, legacy short links block startup on the new backend when short links are enabled. History migration remains a separate command above.

Retention

Retention is disabled by default:

storagePolicy:
  enabled: true
  maxAgeDays: 30
  deletionPolicy: statusOnly

statusOnly deletes old status events while retaining chat; everything deletes all stored messages older than maxAgeDays. Apply a policy immediately with:

relay storage clean

An optional username limits cleanup to one account. Relay also activates the cleaner at startup. The default age is seven days when enabled; this example selects 30. Policy changes in YAML require a restart.

Danger

Retention deletion cannot be undone through Relay. Confirm backups and policy scope before enabling it.

PostgreSQL with Compose

Add a PostgreSQL service with persistent storage and a health check, then use its Compose service name in Relay's connection string. Put the password in a protected environment or secret rather than committing it, configure Relay before migrating history, and do not remove either volume during the change.

See Backup, restore, and upgrades before migration or deletion.