Skip to content

Storage & backups

The server loads users, roles, channels, and webhooks into memory for synchronous access. Disk remains the durability boundary.

Data Shape
config.json Resolved from operator overrides plus defaults
users.json Object keyed by internal Rotur user ID
roles.json Object keyed by role name
channels.json Ordered array of channel and separator records
Channel/thread messages Numbered JSONL shards, 1,000 records per shard
Threads, unreads, polls, reports, webhooks, audit log Focused indexes/files managed under their DB modules
Attachments and custom assets Local files or configured S3-compatible backend plus metadata

Stored messages use internal user IDs. Public serialization turns those into usernames and hydrates replies, reactions, mentions, interactions, and polls.

Mutable JSON indexes use a temporary file followed by rename where implemented. In-memory mutations keep the previous value and roll back when persistence fails. Message creation persists before its broadcast is returned; edits rewrite the containing shard; deletion rewrites/removes stored records and cleans up attachments.

Back up the entire selected database directory together. For the cleanest snapshot, stop the process or quiesce writes before copying. If attachments use S3-compatible storage, back up both metadata and the bucket according to one retention point.

Never commit a live database, generated originchats-osl binary, config.json containing secrets, or attachment content to the source repository.