# Database schemas and migrations RustBox 0.2.15 keeps SQL, blob storage and search as independent concerns: ```text database_backend = sqlite | mysql | pgsql session_backend = database | redis storage.backend = filesystem | s3 search.backend = disabled | local_tantivy | opensearch ``` When `session_backend = "database"`, sessions live in the selected SQL database. `session_backend = "redis"` moves only session persistence to Redis/Redis Sentinel. ## Layout ```text migrations/ ├── sqlite/ │ ├── schema.sql │ ├── V047__blob_keys_and_search_outbox.sql │ ├── V048__folder_counter_generation.sql │ ├── V049__blob_delete_outbox.sql │ └── V050__compact_rows_and_signature_mode.sql ├── mysql/ │ ├── schema.sql │ ├── V047__blob_keys_and_search_outbox.sql │ ├── V048__folder_counter_generation.sql │ ├── V049__blob_delete_outbox.sql │ └── V050__compact_rows_and_signature_mode.sql └── pgsql/ ├── schema.sql ├── V047__blob_keys_and_search_outbox.sql ├── V048__folder_counter_generation.sql ├── V049__blob_delete_outbox.sql └── V050__compact_rows_and_signature_mode.sql ``` Each `schema.sql` is the current complete schema for fresh installations. The historical compatibility baseline remains **V046**. RustBox 0.2.1 adds **V047**, which adds attachment SHA-256 metadata and the durable search outbox used by external indexing. RustBox 0.2.8 adds **V048**, which adds the monotonic `folders.counter_generation` used to reject stale IMAP counter writes even when the numeric counts temporarily return to an earlier value. RustBox 0.2.13 adds **V049**, the durable `blob_delete_outbox` used to retry physical object deletion after metadata is removed. RustBox 0.2.14 adds **V050**, which stores the default-on compact wide-row preference and each identity's signature insertion mode (`silent` or `visible`). Account data is isolated inside the selected physical database with a deterministic, collision-checked table prefix derived from the account hash. The `{{p}}` marker in tenant SQL is replaced by RustBox at provisioning/migration time. Sessions are global and therefore are not prefixed. ## Runtime migrations Every schema-changing release must add the same logical migration for all supported SQL engines and register it in `src/db/pool.rs`. Do not update only `schema.sql`: fresh installs use the baseline while existing installations use the numbered migration path. RustBox 0.2.14 adds runtime migration **V050** on SQLite, MySQL and PostgreSQL. **V051** is the next migration number. Redis and Redis Sentinel do not use SQL migrations. ## Engine notes - SQLite uses `data_dir/rustbox.sqlite` by default; `database_url` may point to another persistent SQLite file. - MySQL requires `database_url` and targets MySQL 8.0.13 or newer. - PostgreSQL requires `database_url`. - MySQL/PostgreSQL are full application backends, not session-only databases. - The SQL engine does not choose blob/search storage. PostgreSQL/MySQL may still use local filesystem/Tantivy in single-node mode. - Cluster mode requires a shared MySQL/PostgreSQL database plus cluster-safe blob/search choices; local `data_dir` is not inherently required.